[ObjCExport][Minor] Reformat Code after move into newly created modules
FL-23390
This commit is contained in:
committed by
Space Team
parent
5fba2962b9
commit
e97463afb3
@@ -29,9 +29,9 @@ fun KotlinType.binaryRepresentationIsNullable() = KotlinTypeInlineClassesSupport
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
inline fun <R> KotlinType.unwrapToPrimitiveOrReference(
|
||||
eachInlinedClass: (inlinedClass: ClassDescriptor, nullable: Boolean) -> Unit,
|
||||
ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R,
|
||||
ifReference: (type: KotlinType) -> R
|
||||
eachInlinedClass: (inlinedClass: ClassDescriptor, nullable: Boolean) -> Unit,
|
||||
ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R,
|
||||
ifReference: (type: KotlinType) -> R,
|
||||
): R = KotlinTypeInlineClassesSupport.unwrapToPrimitiveOrReference(this, eachInlinedClass, ifPrimitive, ifReference)
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ inline fun <R> KotlinType.unwrapToPrimitiveOrReference(
|
||||
fun KotlinType.binaryTypeIsReference(): Boolean = this.computePrimitiveBinaryTypeOrNull() == null
|
||||
|
||||
fun KotlinType.computePrimitiveBinaryTypeOrNull(): PrimitiveBinaryType? =
|
||||
this.computeBinaryType().primitiveBinaryTypeOrNull()
|
||||
this.computeBinaryType().primitiveBinaryTypeOrNull()
|
||||
|
||||
fun KotlinType.computeBinaryType(): BinaryType<ClassDescriptor> = KotlinTypeInlineClassesSupport.computeBinaryType(this)
|
||||
|
||||
@@ -74,9 +74,9 @@ enum class KonanPrimitiveType(val classId: ClassId, val binaryType: BinaryType.P
|
||||
assert(!it.classId.isNestedClass)
|
||||
it.classId.packageFqName
|
||||
}.fold({ _, _ -> mutableMapOf<Name, KonanPrimitiveType>() },
|
||||
{ _, accumulator, element ->
|
||||
accumulator.also { it[element.classId.shortClassName] = element }
|
||||
})
|
||||
{ _, accumulator, element ->
|
||||
accumulator.also { it[element.classId.shortClassName] = element }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,12 +84,14 @@ enum class KonanPrimitiveType(val classId: ClassId, val binaryType: BinaryType.P
|
||||
abstract class InlineClassesSupport<Class : Any, Type : Any> {
|
||||
@InternalKotlinNativeApi
|
||||
abstract fun isNullable(type: Type): Boolean
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
abstract fun makeNullable(type: Type): Type
|
||||
protected abstract fun erase(type: Type): Class
|
||||
protected abstract fun computeFullErasure(type: Type): Sequence<Class>
|
||||
protected abstract fun hasInlineModifier(clazz: Class): Boolean
|
||||
protected abstract fun getNativePointedSuperclass(clazz: Class): Class?
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
abstract fun getInlinedClassUnderlyingType(clazz: Class): Type
|
||||
protected abstract fun getPackageFqName(clazz: Class): FqName?
|
||||
@@ -103,19 +105,20 @@ abstract class InlineClassesSupport<Class : Any, Type : Any> {
|
||||
fun isUsedAsBoxClass(clazz: Class) = getInlinedClass(clazz) == clazz // To handle NativePointed subclasses.
|
||||
|
||||
fun getInlinedClass(type: Type): Class? =
|
||||
getInlinedClass(erase(type), isNullable(type))
|
||||
getInlinedClass(erase(type), isNullable(type))
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
fun getKonanPrimitiveType(clazz: Class): KonanPrimitiveType? =
|
||||
if (isTopLevelClass(clazz))
|
||||
KonanPrimitiveType.byFqNameParts[getPackageFqName(clazz)]?.get(getName(clazz))
|
||||
else null
|
||||
if (isTopLevelClass(clazz))
|
||||
KonanPrimitiveType.byFqNameParts[getPackageFqName(clazz)]?.get(getName(clazz))
|
||||
else null
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
fun isImplicitInlineClass(clazz: Class): Boolean =
|
||||
isTopLevelClass(clazz) && (getKonanPrimitiveType(clazz) != null ||
|
||||
getName(clazz) == KonanFqNames.nativePtr.shortName() && getPackageFqName(clazz) == KonanFqNames.internalPackageName ||
|
||||
getName(clazz) == InteropFqNames.cPointer.shortName() && getPackageFqName(clazz) == InteropFqNames.cPointer.parent().toSafe())
|
||||
isTopLevelClass(clazz) && (getKonanPrimitiveType(clazz) != null ||
|
||||
getName(clazz) == KonanFqNames.nativePtr.shortName() && getPackageFqName(clazz) == KonanFqNames.internalPackageName ||
|
||||
getName(clazz) == InteropFqNames.cPointer.shortName() && getPackageFqName(clazz) == InteropFqNames.cPointer.parent()
|
||||
.toSafe())
|
||||
|
||||
private fun getInlinedClass(erased: Class, isNullable: Boolean): Class? {
|
||||
val inlinedClass = getInlinedClass(erased) ?: return null
|
||||
@@ -144,17 +147,17 @@ abstract class InlineClassesSupport<Class : Any, Type : Any> {
|
||||
|
||||
@JvmName("classGetInlinedClass")
|
||||
private fun getInlinedClass(clazz: Class): Class? =
|
||||
if (hasInlineModifier(clazz) || isImplicitInlineClass(clazz)) {
|
||||
clazz
|
||||
} else {
|
||||
getNativePointedSuperclass(clazz)
|
||||
}
|
||||
if (hasInlineModifier(clazz) || isImplicitInlineClass(clazz)) {
|
||||
clazz
|
||||
} else {
|
||||
getNativePointedSuperclass(clazz)
|
||||
}
|
||||
|
||||
inline fun <R> unwrapToPrimitiveOrReference(
|
||||
type: Type,
|
||||
eachInlinedClass: (inlinedClass: Class, nullable: Boolean) -> Unit,
|
||||
ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R,
|
||||
ifReference: (type: Type) -> R
|
||||
type: Type,
|
||||
eachInlinedClass: (inlinedClass: Class, nullable: Boolean) -> Unit,
|
||||
ifPrimitive: (primitiveType: KonanPrimitiveType, nullable: Boolean) -> R,
|
||||
ifReference: (type: Type) -> R,
|
||||
): R {
|
||||
var currentType: Type = type
|
||||
|
||||
@@ -179,10 +182,10 @@ abstract class InlineClassesSupport<Class : Any, Type : Any> {
|
||||
|
||||
fun representationIsNullable(type: Type): Boolean {
|
||||
unwrapToPrimitiveOrReference(
|
||||
type,
|
||||
eachInlinedClass = { _, nullable -> if (nullable) return true },
|
||||
ifPrimitive = { _, nullable -> return nullable },
|
||||
ifReference = { return isNullable(it) }
|
||||
type,
|
||||
eachInlinedClass = { _, nullable -> if (nullable) return true },
|
||||
ifPrimitive = { _, nullable -> return nullable },
|
||||
ifReference = { return isNullable(it) }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -204,7 +207,7 @@ abstract class InlineClassesSupport<Class : Any, Type : Any> {
|
||||
}
|
||||
|
||||
private fun createReferenceBinaryType(type: Type): BinaryType.Reference<Class> =
|
||||
BinaryType.Reference(computeFullErasure(type), true)
|
||||
BinaryType.Reference(computeFullErasure(type), true)
|
||||
}
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
@@ -230,16 +233,16 @@ object KotlinTypeInlineClassesSupport : InlineClassesSupport<ClassDescriptor, Ko
|
||||
override fun hasInlineModifier(clazz: ClassDescriptor): Boolean = clazz.isInlineClass()
|
||||
|
||||
override fun getNativePointedSuperclass(clazz: ClassDescriptor): ClassDescriptor? = clazz.getAllSuperClassifiers()
|
||||
.firstOrNull { it.fqNameUnsafe == InteropFqNames.nativePointed } as ClassDescriptor?
|
||||
.firstOrNull { it.fqNameUnsafe == InteropFqNames.nativePointed } as ClassDescriptor?
|
||||
|
||||
override fun getInlinedClassUnderlyingType(clazz: ClassDescriptor): KotlinType =
|
||||
clazz.unsubstitutedPrimaryConstructor!!.valueParameters.single().type
|
||||
clazz.unsubstitutedPrimaryConstructor!!.valueParameters.single().type
|
||||
|
||||
override fun getPackageFqName(clazz: ClassDescriptor) =
|
||||
clazz.findPackage().fqName
|
||||
clazz.findPackage().fqName
|
||||
|
||||
override fun getName(clazz: ClassDescriptor) =
|
||||
clazz.name
|
||||
clazz.name
|
||||
|
||||
override fun isTopLevelClass(clazz: ClassDescriptor): Boolean = clazz.containingDeclaration is PackageFragmentDescriptor
|
||||
}
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ package org.jetbrains.kotlin.backend.konan
|
||||
* It is not safe to depend on any internal Kotlin/Native API outside kotlin.git/kotlin-native
|
||||
*/
|
||||
@RequiresOptIn(
|
||||
"This API is internal to the Kotlin/Native compiler and cannot be used outside of kotlin.git",
|
||||
level = RequiresOptIn.Level.ERROR
|
||||
"This API is internal to the Kotlin/Native compiler and cannot be used outside of kotlin.git",
|
||||
level = RequiresOptIn.Level.ERROR
|
||||
)
|
||||
annotation class InternalKotlinNativeApi
|
||||
|
||||
@@ -106,11 +106,11 @@ class InteropBuiltIns(builtIns: KonanBuiltIns) {
|
||||
}
|
||||
|
||||
private fun MemberScope.getContributedVariables(name: String) =
|
||||
this.getContributedVariables(Name.identifier(name), NoLookupLocation.FROM_BUILTINS)
|
||||
this.getContributedVariables(Name.identifier(name), NoLookupLocation.FROM_BUILTINS)
|
||||
|
||||
internal fun MemberScope.getContributedClass(name: String): ClassDescriptor =
|
||||
this.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) as ClassDescriptor
|
||||
this.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BUILTINS) as ClassDescriptor
|
||||
|
||||
private fun MemberScope.getContributedFunctions(name: String) =
|
||||
this.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS)
|
||||
this.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS)
|
||||
|
||||
|
||||
@@ -7,42 +7,42 @@ package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
val cKeywords = setOf(
|
||||
// Actual C keywords.
|
||||
"auto", "break", "case",
|
||||
"char", "const", "continue",
|
||||
"default", "do", "double",
|
||||
"else", "enum", "extern",
|
||||
"float", "for", "goto",
|
||||
"if", "int", "long",
|
||||
"register", "return",
|
||||
"short", "signed", "sizeof", "static", "struct", "switch",
|
||||
"typedef", "union", "unsigned",
|
||||
"void", "volatile", "while",
|
||||
// C99-specific.
|
||||
"_Bool", "_Complex", "_Imaginary", "inline", "restrict",
|
||||
// C11-specific.
|
||||
"_Alignas", "_Alignof", "_Atomic", "_Generic", "_Noreturn", "_Static_assert", "_Thread_local",
|
||||
// Not exactly keywords, but reserved or standard-defined.
|
||||
"and", "not", "or", "xor",
|
||||
"bool", "complex", "imaginary",
|
||||
// Actual C keywords.
|
||||
"auto", "break", "case",
|
||||
"char", "const", "continue",
|
||||
"default", "do", "double",
|
||||
"else", "enum", "extern",
|
||||
"float", "for", "goto",
|
||||
"if", "int", "long",
|
||||
"register", "return",
|
||||
"short", "signed", "sizeof", "static", "struct", "switch",
|
||||
"typedef", "union", "unsigned",
|
||||
"void", "volatile", "while",
|
||||
// C99-specific.
|
||||
"_Bool", "_Complex", "_Imaginary", "inline", "restrict",
|
||||
// C11-specific.
|
||||
"_Alignas", "_Alignof", "_Atomic", "_Generic", "_Noreturn", "_Static_assert", "_Thread_local",
|
||||
// Not exactly keywords, but reserved or standard-defined.
|
||||
"and", "not", "or", "xor",
|
||||
"bool", "complex", "imaginary",
|
||||
|
||||
// C++ keywords not listed above.
|
||||
"alignas", "alignof", "and_eq", "asm",
|
||||
"bitand", "bitor", "bool",
|
||||
"catch", "char16_t", "char32_t", "class", "compl", "constexpr", "const_cast",
|
||||
"decltype", "delete", "dynamic_cast",
|
||||
"explicit", "export",
|
||||
"false", "friend",
|
||||
"inline",
|
||||
"mutable",
|
||||
"namespace", "new", "noexcept", "not_eq", "nullptr",
|
||||
"operator", "or_eq",
|
||||
"private", "protected", "public",
|
||||
"reinterpret_cast",
|
||||
"static_assert",
|
||||
"template", "this", "thread_local", "throw", "true", "try", "typeid", "typename",
|
||||
"using",
|
||||
"virtual",
|
||||
"wchar_t",
|
||||
"xor_eq"
|
||||
// C++ keywords not listed above.
|
||||
"alignas", "alignof", "and_eq", "asm",
|
||||
"bitand", "bitor", "bool",
|
||||
"catch", "char16_t", "char32_t", "class", "compl", "constexpr", "const_cast",
|
||||
"decltype", "delete", "dynamic_cast",
|
||||
"explicit", "export",
|
||||
"false", "friend",
|
||||
"inline",
|
||||
"mutable",
|
||||
"namespace", "new", "noexcept", "not_eq", "nullptr",
|
||||
"operator", "or_eq",
|
||||
"private", "protected", "public",
|
||||
"reinterpret_cast",
|
||||
"static_assert",
|
||||
"template", "this", "thread_local", "throw", "true", "try", "typeid", "typename",
|
||||
"using",
|
||||
"virtual",
|
||||
"wchar_t",
|
||||
"xor_eq"
|
||||
)
|
||||
|
||||
+25
-25
@@ -111,7 +111,7 @@ private fun getPackagesFqNames(module: ModuleDescriptor): Set<FqName> {
|
||||
fun getSubPackages(fqName: FqName) {
|
||||
result.add(fqName)
|
||||
val subPackages = packageFragmentProvider?.getSubPackagesOf(fqName) { true }
|
||||
?: module.getSubPackagesOf(fqName) { true }
|
||||
?: module.getSubPackagesOf(fqName) { true }
|
||||
subPackages.forEach { getSubPackages(it) }
|
||||
}
|
||||
|
||||
@@ -120,16 +120,16 @@ private fun getPackagesFqNames(module: ModuleDescriptor): Set<FqName> {
|
||||
}
|
||||
|
||||
fun ModuleDescriptor.getPackageFragments(): List<PackageFragmentDescriptor> =
|
||||
getPackagesFqNames(this).flatMap {
|
||||
getPackage(it).fragments.filter { it.module == this }.toSet()
|
||||
}
|
||||
getPackagesFqNames(this).flatMap {
|
||||
getPackage(it).fragments.filter { it.module == this }.toSet()
|
||||
}
|
||||
|
||||
val ClassDescriptor.enumEntries: List<ClassDescriptor>
|
||||
get() {
|
||||
assert(this.kind == ClassKind.ENUM_CLASS)
|
||||
return this.unsubstitutedMemberScope.getContributedDescriptors()
|
||||
.filterIsInstance<ClassDescriptor>()
|
||||
.filter { it.kind == ClassKind.ENUM_ENTRY }
|
||||
.filterIsInstance<ClassDescriptor>()
|
||||
.filter { it.kind == ClassKind.ENUM_ENTRY }
|
||||
}
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
@@ -138,27 +138,27 @@ val DeclarationDescriptor.isExpectMember: Boolean
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
val arrayTypes = setOf(
|
||||
"kotlin.Array",
|
||||
"kotlin.ByteArray",
|
||||
"kotlin.CharArray",
|
||||
"kotlin.ShortArray",
|
||||
"kotlin.IntArray",
|
||||
"kotlin.LongArray",
|
||||
"kotlin.FloatArray",
|
||||
"kotlin.DoubleArray",
|
||||
"kotlin.BooleanArray",
|
||||
"kotlin.native.ImmutableBlob",
|
||||
"kotlin.native.internal.NativePtrArray"
|
||||
"kotlin.Array",
|
||||
"kotlin.ByteArray",
|
||||
"kotlin.CharArray",
|
||||
"kotlin.ShortArray",
|
||||
"kotlin.IntArray",
|
||||
"kotlin.LongArray",
|
||||
"kotlin.FloatArray",
|
||||
"kotlin.DoubleArray",
|
||||
"kotlin.BooleanArray",
|
||||
"kotlin.native.ImmutableBlob",
|
||||
"kotlin.native.internal.NativePtrArray"
|
||||
)
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
val arraysWithFixedSizeItems = setOf(
|
||||
"kotlin.ByteArray",
|
||||
"kotlin.CharArray",
|
||||
"kotlin.ShortArray",
|
||||
"kotlin.IntArray",
|
||||
"kotlin.LongArray",
|
||||
"kotlin.FloatArray",
|
||||
"kotlin.DoubleArray",
|
||||
"kotlin.BooleanArray"
|
||||
"kotlin.ByteArray",
|
||||
"kotlin.CharArray",
|
||||
"kotlin.ShortArray",
|
||||
"kotlin.IntArray",
|
||||
"kotlin.LongArray",
|
||||
"kotlin.FloatArray",
|
||||
"kotlin.DoubleArray",
|
||||
"kotlin.BooleanArray"
|
||||
)
|
||||
+41
-25
@@ -18,14 +18,18 @@ import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
fun ClassDescriptor.isMappedFunctionClass() =
|
||||
this.getFunctionTypeKind() == FunctionTypeKind.Function &&
|
||||
// Type parameters include return type.
|
||||
declaredTypeParameters.size - 1 < CustomTypeMappers.functionTypeMappersArityLimit
|
||||
this.getFunctionTypeKind() == FunctionTypeKind.Function &&
|
||||
// Type parameters include return type.
|
||||
declaredTypeParameters.size - 1 < CustomTypeMappers.functionTypeMappersArityLimit
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
interface CustomTypeMapper {
|
||||
val mappedClassId: ClassId
|
||||
fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType
|
||||
fun mapType(
|
||||
mappedSuperType: KotlinType,
|
||||
translator: ObjCExportTranslatorImpl,
|
||||
objCExportScope: ObjCExportScope,
|
||||
): ObjCNonNullReferenceType
|
||||
}
|
||||
|
||||
internal object CustomTypeMappers {
|
||||
@@ -89,44 +93,52 @@ internal object CustomTypeMappers {
|
||||
* Note: can be generated programmatically, but requires stdlib in this case.
|
||||
*/
|
||||
val hiddenTypes: Set<ClassId> = listOf(
|
||||
"kotlin.Any",
|
||||
"kotlin.CharSequence",
|
||||
"kotlin.Comparable",
|
||||
"kotlin.Function",
|
||||
"kotlin.Number",
|
||||
"kotlin.collections.Collection",
|
||||
"kotlin.collections.Iterable",
|
||||
"kotlin.collections.MutableCollection",
|
||||
"kotlin.collections.MutableIterable"
|
||||
"kotlin.Any",
|
||||
"kotlin.CharSequence",
|
||||
"kotlin.Comparable",
|
||||
"kotlin.Function",
|
||||
"kotlin.Number",
|
||||
"kotlin.collections.Collection",
|
||||
"kotlin.collections.Iterable",
|
||||
"kotlin.collections.MutableCollection",
|
||||
"kotlin.collections.MutableIterable"
|
||||
).map { ClassId.topLevel(FqName(it)) }.toSet()
|
||||
|
||||
private class Simple(
|
||||
override val mappedClassId: ClassId,
|
||||
private val getObjCClassName: ObjCExportTranslatorImpl.() -> String
|
||||
override val mappedClassId: ClassId,
|
||||
private val getObjCClassName: ObjCExportTranslatorImpl.() -> String,
|
||||
) : CustomTypeMapper {
|
||||
|
||||
constructor(
|
||||
mappedClassId: ClassId,
|
||||
objCClassName: String
|
||||
mappedClassId: ClassId,
|
||||
objCClassName: String,
|
||||
) : this(mappedClassId, { objCClassName })
|
||||
|
||||
override fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType =
|
||||
ObjCClassType(translator.getObjCClassName())
|
||||
override fun mapType(
|
||||
mappedSuperType: KotlinType,
|
||||
translator: ObjCExportTranslatorImpl,
|
||||
objCExportScope: ObjCExportScope,
|
||||
): ObjCNonNullReferenceType =
|
||||
ObjCClassType(translator.getObjCClassName())
|
||||
}
|
||||
|
||||
private class Collection(
|
||||
mappedClassFqName: FqName,
|
||||
private val getObjCClassName: ObjCExportTranslatorImpl.() -> String
|
||||
mappedClassFqName: FqName,
|
||||
private val getObjCClassName: ObjCExportTranslatorImpl.() -> String,
|
||||
) : CustomTypeMapper {
|
||||
|
||||
constructor(
|
||||
mappedClassFqName: FqName,
|
||||
objCClassName: String
|
||||
mappedClassFqName: FqName,
|
||||
objCClassName: String,
|
||||
) : this(mappedClassFqName, { objCClassName })
|
||||
|
||||
override val mappedClassId = ClassId.topLevel(mappedClassFqName)
|
||||
|
||||
override fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType {
|
||||
override fun mapType(
|
||||
mappedSuperType: KotlinType,
|
||||
translator: ObjCExportTranslatorImpl,
|
||||
objCExportScope: ObjCExportScope,
|
||||
): ObjCNonNullReferenceType {
|
||||
val typeArguments = mappedSuperType.arguments.map {
|
||||
val argument = it.type
|
||||
if (TypeUtils.isNullableType(argument)) {
|
||||
@@ -145,7 +157,11 @@ internal object CustomTypeMappers {
|
||||
override val mappedClassId: ClassId
|
||||
get() = StandardNames.getFunctionClassId(parameterCount)
|
||||
|
||||
override fun mapType(mappedSuperType: KotlinType, translator: ObjCExportTranslatorImpl, objCExportScope: ObjCExportScope): ObjCNonNullReferenceType {
|
||||
override fun mapType(
|
||||
mappedSuperType: KotlinType,
|
||||
translator: ObjCExportTranslatorImpl,
|
||||
objCExportScope: ObjCExportScope,
|
||||
): ObjCNonNullReferenceType {
|
||||
return translator.mapFunctionTypeIgnoringNullability(mappedSuperType, objCExportScope, returnsVoid = false)
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -18,14 +18,14 @@ import org.jetbrains.kotlin.name.isSubpackageOf
|
||||
@InternalKotlinNativeApi
|
||||
class MainPackageGuesser {
|
||||
fun guess(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
includedLibraryDescriptors: List<ModuleDescriptor>,
|
||||
exportedDependencies: List<ModuleDescriptor>,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
includedLibraryDescriptors: List<ModuleDescriptor>,
|
||||
exportedDependencies: List<ModuleDescriptor>,
|
||||
): FqName {
|
||||
// Consider exported libraries only if we cannot infer the package from sources or included libs.
|
||||
return guessMainPackage(includedLibraryDescriptors + moduleDescriptor)
|
||||
?: guessMainPackage(exportedDependencies)
|
||||
?: FqName.ROOT
|
||||
?: guessMainPackage(exportedDependencies)
|
||||
?: FqName.ROOT
|
||||
}
|
||||
|
||||
private fun guessMainPackage(modules: List<ModuleDescriptor>): FqName? {
|
||||
@@ -38,12 +38,12 @@ class MainPackageGuesser {
|
||||
}
|
||||
|
||||
val nonEmptyPackages = allPackages
|
||||
.filter { it.getMemberScope().getContributedDescriptors().isNotEmpty() }
|
||||
.map { it.fqName }.distinct()
|
||||
.filter { it.getMemberScope().getContributedDescriptors().isNotEmpty() }
|
||||
.map { it.fqName }.distinct()
|
||||
|
||||
return allPackages.map { it.fqName }.distinct()
|
||||
.filter { candidate -> nonEmptyPackages.all { it.isSubpackageOf(candidate) } }
|
||||
// Now there are all common ancestors of non-empty packages. Longest of them is the least common accessor:
|
||||
.maxByOrNull { it.asString().length }
|
||||
.filter { candidate -> nonEmptyPackages.all { it.isSubpackageOf(candidate) } }
|
||||
// Now there are all common ancestors of non-empty packages. Longest of them is the least common accessor:
|
||||
.maxByOrNull { it.asString().length }
|
||||
}
|
||||
}
|
||||
+16
-16
@@ -9,9 +9,6 @@ import org.jetbrains.kotlin.backend.common.descriptors.allParameters
|
||||
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.util.allParameters
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
sealed class TypeBridge
|
||||
@@ -21,8 +18,8 @@ object ReferenceBridge : TypeBridge()
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
data class BlockPointerBridge(
|
||||
val numberOfParameters: Int,
|
||||
val returnsVoid: Boolean
|
||||
val numberOfParameters: Int,
|
||||
val returnsVoid: Boolean,
|
||||
) : TypeBridge()
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
@@ -50,9 +47,9 @@ sealed class MethodBridgeValueParameter : MethodBridgeParameter() {
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
data class MethodBridge(
|
||||
val returnBridge: ReturnValue,
|
||||
val receiver: MethodBridgeReceiver,
|
||||
val valueParameters: List<MethodBridgeValueParameter>
|
||||
val returnBridge: ReturnValue,
|
||||
val receiver: MethodBridgeReceiver,
|
||||
val valueParameters: List<MethodBridgeValueParameter>,
|
||||
) {
|
||||
|
||||
sealed class ReturnValue {
|
||||
@@ -73,15 +70,17 @@ data class MethodBridge(
|
||||
}
|
||||
|
||||
val paramBridges: List<MethodBridgeParameter> =
|
||||
listOf(receiver) + MethodBridgeSelector + valueParameters
|
||||
listOf(receiver) + MethodBridgeSelector + valueParameters
|
||||
|
||||
// TODO: it is not exactly true in potential future cases.
|
||||
val isInstance: Boolean get() = when (receiver) {
|
||||
MethodBridgeReceiver.Static,
|
||||
MethodBridgeReceiver.Factory -> false
|
||||
val isInstance: Boolean
|
||||
get() = when (receiver) {
|
||||
MethodBridgeReceiver.Static,
|
||||
MethodBridgeReceiver.Factory,
|
||||
-> false
|
||||
|
||||
MethodBridgeReceiver.Instance -> true
|
||||
}
|
||||
MethodBridgeReceiver.Instance -> true
|
||||
}
|
||||
|
||||
val returnsError: Boolean
|
||||
get() = returnBridge is ReturnValue.WithError
|
||||
@@ -89,7 +88,7 @@ data class MethodBridge(
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
fun MethodBridge.valueParametersAssociated(
|
||||
descriptor: FunctionDescriptor
|
||||
descriptor: FunctionDescriptor,
|
||||
): List<Pair<MethodBridgeValueParameter, ParameterDescriptor?>> {
|
||||
val kotlinParameters = descriptor.allParameters.iterator()
|
||||
val skipFirstKotlinParameter = when (this.receiver) {
|
||||
@@ -105,7 +104,8 @@ fun MethodBridge.valueParametersAssociated(
|
||||
is MethodBridgeValueParameter.Mapped -> it to kotlinParameters.next()
|
||||
|
||||
is MethodBridgeValueParameter.SuspendCompletion,
|
||||
is MethodBridgeValueParameter.ErrorOutParameter -> it to null
|
||||
is MethodBridgeValueParameter.ErrorOutParameter,
|
||||
-> it to null
|
||||
}
|
||||
}.also { assert(!kotlinParameters.hasNext()) }
|
||||
}
|
||||
|
||||
+321
-294
File diff suppressed because it is too large
Load Diff
+8
-8
@@ -8,14 +8,14 @@ package org.jetbrains.kotlin.backend.konan.objcexport
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
|
||||
internal class ObjCExportHeaderGeneratorImpl(
|
||||
moduleDescriptors: List<ModuleDescriptor>,
|
||||
mapper: ObjCExportMapper,
|
||||
namer: ObjCExportNamer,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
objcGenerics: Boolean,
|
||||
override val shouldExportKDoc: Boolean,
|
||||
private val additionalImports: List<String>,
|
||||
moduleDescriptors: List<ModuleDescriptor>,
|
||||
mapper: ObjCExportMapper,
|
||||
namer: ObjCExportNamer,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
objcGenerics: Boolean,
|
||||
override val shouldExportKDoc: Boolean,
|
||||
private val additionalImports: List<String>,
|
||||
) : ObjCExportHeaderGenerator(moduleDescriptors, mapper, namer, objcGenerics, problemCollector) {
|
||||
override fun getAdditionalImports(): List<String> =
|
||||
additionalImports
|
||||
additionalImports
|
||||
}
|
||||
|
||||
+106
-103
@@ -9,12 +9,12 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.backend.konan.InternalKotlinNativeApi
|
||||
import org.jetbrains.kotlin.backend.konan.UnitSuspendFunctionObjCExport
|
||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -61,35 +61,35 @@ interface ObjCExportLazy {
|
||||
|
||||
@JvmOverloads
|
||||
fun createObjCExportLazy(
|
||||
configuration: ObjCExportLazy.Configuration,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
codeAnalyzer: KotlinCodeAnalyzer,
|
||||
typeResolver: TypeResolver,
|
||||
descriptorResolver: DescriptorResolver,
|
||||
fileScopeProvider: FileScopeProvider,
|
||||
builtIns: KotlinBuiltIns,
|
||||
deprecationResolver: DeprecationResolver? = null
|
||||
configuration: ObjCExportLazy.Configuration,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
codeAnalyzer: KotlinCodeAnalyzer,
|
||||
typeResolver: TypeResolver,
|
||||
descriptorResolver: DescriptorResolver,
|
||||
fileScopeProvider: FileScopeProvider,
|
||||
builtIns: KotlinBuiltIns,
|
||||
deprecationResolver: DeprecationResolver? = null,
|
||||
): ObjCExportLazy = ObjCExportLazyImpl(
|
||||
configuration,
|
||||
problemCollector,
|
||||
codeAnalyzer,
|
||||
typeResolver,
|
||||
descriptorResolver,
|
||||
fileScopeProvider,
|
||||
builtIns,
|
||||
deprecationResolver
|
||||
configuration,
|
||||
problemCollector,
|
||||
codeAnalyzer,
|
||||
typeResolver,
|
||||
descriptorResolver,
|
||||
fileScopeProvider,
|
||||
builtIns,
|
||||
deprecationResolver
|
||||
)
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
class ObjCExportLazyImpl(
|
||||
private val configuration: ObjCExportLazy.Configuration,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
private val codeAnalyzer: KotlinCodeAnalyzer,
|
||||
private val typeResolver: TypeResolver,
|
||||
private val descriptorResolver: DescriptorResolver,
|
||||
private val fileScopeProvider: FileScopeProvider,
|
||||
builtIns: KotlinBuiltIns,
|
||||
deprecationResolver: DeprecationResolver?
|
||||
private val configuration: ObjCExportLazy.Configuration,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
private val codeAnalyzer: KotlinCodeAnalyzer,
|
||||
private val typeResolver: TypeResolver,
|
||||
private val descriptorResolver: DescriptorResolver,
|
||||
private val fileScopeProvider: FileScopeProvider,
|
||||
builtIns: KotlinBuiltIns,
|
||||
deprecationResolver: DeprecationResolver?,
|
||||
) : ObjCExportLazy {
|
||||
|
||||
private val namerConfiguration = createNamerConfiguration(configuration)
|
||||
@@ -101,11 +101,11 @@ class ObjCExportLazyImpl(
|
||||
private val namer = ObjCExportNamerImpl(namerConfiguration, builtIns, mapper, problemCollector, local = true)
|
||||
|
||||
private val translator: ObjCExportTranslator = ObjCExportTranslatorImpl(
|
||||
null,
|
||||
mapper,
|
||||
namer,
|
||||
problemCollector,
|
||||
configuration.objcGenerics
|
||||
null,
|
||||
mapper,
|
||||
namer,
|
||||
problemCollector,
|
||||
configuration.objcGenerics
|
||||
)
|
||||
|
||||
private val isValid: Boolean
|
||||
@@ -114,14 +114,15 @@ class ObjCExportLazyImpl(
|
||||
override fun generateBase() = translator.generateBaseDeclarations()
|
||||
|
||||
override fun translate(file: KtFile): List<ObjCTopLevel<*>> =
|
||||
translateClasses(file) + translateTopLevels(file)
|
||||
translateClasses(file) + translateTopLevels(file)
|
||||
|
||||
private fun translateClasses(container: KtDeclarationContainer): List<ObjCClass<*>> {
|
||||
val result = mutableListOf<ObjCClass<*>>()
|
||||
container.declarations.forEach { declaration ->
|
||||
// Supposed to be true if ObjCExportMapper.shouldBeVisible is true.
|
||||
if (declaration is KtClassOrObject && declaration.isPublic && declaration !is KtEnumEntry
|
||||
&& !declaration.hasExpectModifier()) {
|
||||
&& !declaration.hasExpectModifier()
|
||||
) {
|
||||
|
||||
if (!declaration.isAnnotation() && !declaration.hasModifier(KtTokens.INLINE_KEYWORD)) {
|
||||
result += translateClass(declaration)
|
||||
@@ -144,7 +145,7 @@ class ObjCExportLazyImpl(
|
||||
LazyObjCProtocolImpl(name, ktClassOrObject, this)
|
||||
} else {
|
||||
val isFinal = ktClassOrObject.modalityModifier() == null ||
|
||||
ktClassOrObject.hasModifier(KtTokens.FINAL_KEYWORD)
|
||||
ktClassOrObject.hasModifier(KtTokens.FINAL_KEYWORD)
|
||||
|
||||
val attributes = if (isFinal) {
|
||||
listOf(OBJC_SUBCLASSING_RESTRICTED)
|
||||
@@ -152,30 +153,32 @@ class ObjCExportLazyImpl(
|
||||
emptyList()
|
||||
}
|
||||
|
||||
LazyObjCInterfaceImpl(name,
|
||||
attributes,
|
||||
generics = translateGenerics(ktClassOrObject),
|
||||
psi = ktClassOrObject,
|
||||
lazy = this)
|
||||
LazyObjCInterfaceImpl(
|
||||
name,
|
||||
attributes,
|
||||
generics = translateGenerics(ktClassOrObject),
|
||||
psi = ktClassOrObject,
|
||||
lazy = this
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateGenerics(ktClassOrObject: KtClassOrObject): List<ObjCGenericTypeDeclaration> = if (configuration.objcGenerics) {
|
||||
ktClassOrObject.typeParametersWithOuter
|
||||
.map {
|
||||
ObjCGenericTypeRawDeclaration(
|
||||
nameTranslator.getTypeParameterName(it),
|
||||
ObjCVariance.fromKotlinVariance(it.variance)
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
.map {
|
||||
ObjCGenericTypeRawDeclaration(
|
||||
nameTranslator.getTypeParameterName(it),
|
||||
ObjCVariance.fromKotlinVariance(it.variance)
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
private fun translateTopLevels(file: KtFile): List<ObjCInterface> {
|
||||
val extensions =
|
||||
mutableMapOf<ClassDescriptor, MutableList<KtCallableDeclaration>>()
|
||||
mutableMapOf<ClassDescriptor, MutableList<KtCallableDeclaration>>()
|
||||
|
||||
val topLevel = mutableListOf<KtCallableDeclaration>()
|
||||
|
||||
@@ -212,9 +215,9 @@ class ObjCExportLazyImpl(
|
||||
}
|
||||
|
||||
private fun translateExtensions(
|
||||
file: KtFile,
|
||||
classDescriptor: ClassDescriptor,
|
||||
declarations: List<KtCallableDeclaration>
|
||||
file: KtFile,
|
||||
classDescriptor: ClassDescriptor,
|
||||
declarations: List<KtCallableDeclaration>,
|
||||
): ObjCInterface {
|
||||
// TODO: consider using file-based categories in compiler too.
|
||||
|
||||
@@ -228,13 +231,13 @@ class ObjCExportLazyImpl(
|
||||
}
|
||||
|
||||
private fun resolveDeclaration(ktDeclaration: KtDeclaration): DeclarationDescriptor =
|
||||
codeAnalyzer.resolveToDescriptor(ktDeclaration)
|
||||
codeAnalyzer.resolveToDescriptor(ktDeclaration)
|
||||
|
||||
private fun resolve(ktClassOrObject: KtClassOrObject) =
|
||||
resolveDeclaration(ktClassOrObject) as ClassDescriptor
|
||||
resolveDeclaration(ktClassOrObject) as ClassDescriptor
|
||||
|
||||
private fun resolve(ktCallableDeclaration: KtCallableDeclaration) =
|
||||
resolveDeclaration(ktCallableDeclaration) as CallableMemberDescriptor
|
||||
resolveDeclaration(ktCallableDeclaration) as CallableMemberDescriptor
|
||||
|
||||
private fun getClassIfExtension(topLevelDeclaration: KtCallableDeclaration): ClassDescriptor? {
|
||||
val receiverType = topLevelDeclaration.receiverTypeReference ?: return null
|
||||
@@ -243,19 +246,19 @@ class ObjCExportLazyImpl(
|
||||
val trace = BindingTraceContext() // TODO: revise.
|
||||
|
||||
val kotlinReceiverType = typeResolver.resolveType(
|
||||
createHeaderScope(topLevelDeclaration, fileScope, trace),
|
||||
receiverType,
|
||||
trace,
|
||||
checkBounds = false
|
||||
createHeaderScope(topLevelDeclaration, fileScope, trace),
|
||||
receiverType,
|
||||
trace,
|
||||
checkBounds = false
|
||||
)
|
||||
|
||||
return translator.getClassIfExtension(kotlinReceiverType)
|
||||
}
|
||||
|
||||
private fun createHeaderScope(
|
||||
declaration: KtCallableDeclaration,
|
||||
parent: LexicalScope,
|
||||
trace: BindingTrace
|
||||
declaration: KtCallableDeclaration,
|
||||
parent: LexicalScope,
|
||||
trace: BindingTrace,
|
||||
): LexicalScope {
|
||||
if (declaration.typeParameters.isEmpty()) return parent
|
||||
|
||||
@@ -268,30 +271,30 @@ class ObjCExportLazyImpl(
|
||||
when (declaration) {
|
||||
is KtFunction -> {
|
||||
descriptor = SimpleFunctionDescriptorImpl.create(
|
||||
parent.ownerDescriptor,
|
||||
Annotations.EMPTY,
|
||||
fakeName,
|
||||
CallableMemberDescriptor.Kind.DECLARATION,
|
||||
sourceElement
|
||||
parent.ownerDescriptor,
|
||||
Annotations.EMPTY,
|
||||
fakeName,
|
||||
CallableMemberDescriptor.Kind.DECLARATION,
|
||||
sourceElement
|
||||
)
|
||||
scopeKind = LexicalScopeKind.FUNCTION_HEADER
|
||||
}
|
||||
is KtProperty -> {
|
||||
descriptor = PropertyDescriptorImpl.create(
|
||||
parent.ownerDescriptor,
|
||||
Annotations.EMPTY,
|
||||
Modality.FINAL,
|
||||
DescriptorVisibilities.PUBLIC,
|
||||
declaration.isVar,
|
||||
fakeName,
|
||||
CallableMemberDescriptor.Kind.DECLARATION,
|
||||
sourceElement,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
parent.ownerDescriptor,
|
||||
Annotations.EMPTY,
|
||||
Modality.FINAL,
|
||||
DescriptorVisibilities.PUBLIC,
|
||||
declaration.isVar,
|
||||
fakeName,
|
||||
CallableMemberDescriptor.Kind.DECLARATION,
|
||||
sourceElement,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
)
|
||||
scopeKind = LexicalScopeKind.PROPERTY_HEADER
|
||||
}
|
||||
@@ -299,19 +302,19 @@ class ObjCExportLazyImpl(
|
||||
}
|
||||
|
||||
val result = LexicalWritableScope(
|
||||
parent,
|
||||
descriptor,
|
||||
false,
|
||||
LocalRedeclarationChecker.DO_NOTHING,
|
||||
scopeKind
|
||||
parent,
|
||||
descriptor,
|
||||
false,
|
||||
LocalRedeclarationChecker.DO_NOTHING,
|
||||
scopeKind
|
||||
)
|
||||
|
||||
val typeParameters = descriptorResolver.resolveTypeParametersForDescriptor(
|
||||
descriptor,
|
||||
result,
|
||||
result,
|
||||
declaration.typeParameters,
|
||||
trace
|
||||
descriptor,
|
||||
result,
|
||||
result,
|
||||
declaration.typeParameters,
|
||||
trace
|
||||
)
|
||||
|
||||
descriptorResolver.resolveGenericBounds(declaration, descriptor, result, typeParameters, trace)
|
||||
@@ -322,7 +325,7 @@ class ObjCExportLazyImpl(
|
||||
private class LazyObjCProtocolImpl(
|
||||
name: ObjCExportNamer.ClassOrProtocolName,
|
||||
override val psi: KtClassOrObject,
|
||||
private val lazy: ObjCExportLazyImpl
|
||||
private val lazy: ObjCExportLazyImpl,
|
||||
) : LazyObjCProtocol(name) {
|
||||
override val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) }
|
||||
|
||||
@@ -337,7 +340,7 @@ class ObjCExportLazyImpl(
|
||||
attributes: List<String>,
|
||||
generics: List<ObjCGenericTypeDeclaration>,
|
||||
override val psi: KtClassOrObject,
|
||||
private val lazy: ObjCExportLazyImpl
|
||||
private val lazy: ObjCExportLazyImpl,
|
||||
) : LazyObjCInterface(name = name, generics = generics, categoryName = null, attributes = attributes) {
|
||||
override val descriptor: ClassDescriptor by lazy { lazy.resolve(psi) }
|
||||
|
||||
@@ -351,7 +354,7 @@ class ObjCExportLazyImpl(
|
||||
name: ObjCExportNamer.ClassOrProtocolName,
|
||||
private val file: KtFile,
|
||||
private val declarations: List<KtCallableDeclaration>,
|
||||
private val lazy: ObjCExportLazyImpl
|
||||
private val lazy: ObjCExportLazyImpl,
|
||||
) : LazyObjCInterface(name = name, generics = emptyList(), categoryName = null, attributes = listOf(OBJC_SUBCLASSING_RESTRICTED)) {
|
||||
override val descriptor: ClassDescriptor?
|
||||
get() = null
|
||||
@@ -377,7 +380,7 @@ class ObjCExportLazyImpl(
|
||||
categoryName: String,
|
||||
private val classDescriptor: ClassDescriptor,
|
||||
private val declarations: List<KtCallableDeclaration>,
|
||||
private val lazy: ObjCExportLazyImpl
|
||||
private val lazy: ObjCExportLazyImpl,
|
||||
) : LazyObjCInterface(name = name.objCName, generics = emptyList(), categoryName = categoryName, attributes = emptyList()) {
|
||||
override val descriptor: ClassDescriptor?
|
||||
get() = null
|
||||
@@ -400,17 +403,17 @@ class ObjCExportLazyImpl(
|
||||
private abstract class LazyObjCInterface : ObjCInterface {
|
||||
|
||||
constructor(
|
||||
name: ObjCExportNamer.ClassOrProtocolName,
|
||||
generics: List<ObjCGenericTypeDeclaration>,
|
||||
categoryName: String?,
|
||||
attributes: List<String>
|
||||
name: ObjCExportNamer.ClassOrProtocolName,
|
||||
generics: List<ObjCGenericTypeDeclaration>,
|
||||
categoryName: String?,
|
||||
attributes: List<String>,
|
||||
) : super(name.objCName, generics, categoryName, attributes + name.toNameAttributes())
|
||||
|
||||
constructor(
|
||||
name: String,
|
||||
generics: List<ObjCGenericTypeDeclaration>,
|
||||
categoryName: String,
|
||||
attributes: List<String>
|
||||
name: String,
|
||||
generics: List<ObjCGenericTypeDeclaration>,
|
||||
categoryName: String,
|
||||
attributes: List<String>,
|
||||
) : super(name, generics, categoryName, attributes)
|
||||
|
||||
protected abstract fun computeRealStub(): ObjCInterface
|
||||
@@ -431,7 +434,7 @@ private abstract class LazyObjCInterface : ObjCInterface {
|
||||
}
|
||||
|
||||
private abstract class LazyObjCProtocol(
|
||||
name: ObjCExportNamer.ClassOrProtocolName
|
||||
name: ObjCExportNamer.ClassOrProtocolName,
|
||||
) : ObjCProtocol(name.objCName, name.toNameAttributes()) {
|
||||
|
||||
protected abstract fun computeRealStub(): ObjCProtocol
|
||||
@@ -469,7 +472,7 @@ private val kotlinSequenceClassId = ClassId.topLevel(FqName("kotlin.sequences.Se
|
||||
|
||||
// This is a special workaround needed for resolve in the IDE.
|
||||
private fun ModuleDescriptor.isCommonStdlibCheckSpecificallyForIDE() =
|
||||
findClassAcrossModuleDependencies(kotlinSequenceClassId)?.module == this
|
||||
findClassAcrossModuleDependencies(kotlinSequenceClassId)?.module == this
|
||||
|
||||
private val KtModifierListOwner.isPublic: Boolean
|
||||
get() = this.visibilityModifierTypeOrDefault() == KtTokens.PUBLIC_KEYWORD
|
||||
@@ -479,4 +482,4 @@ internal val KtPureClassOrObject.isInterface: Boolean
|
||||
|
||||
internal val KtClassOrObject.typeParametersWithOuter
|
||||
get() = generateSequence(this, { if (it is KtClass && it.isInner()) it.containingClassOrObject else null })
|
||||
.flatMap { it.typeParameters.asSequence() }
|
||||
.flatMap { it.typeParameters.asSequence() }
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
@InternalKotlinNativeApi
|
||||
fun ObjCExportLazy.dumpObjCHeader(files: Collection<KtFile>, outputFile: String, shouldExportKDoc: Boolean) {
|
||||
val lines = (this.generateBase() + files.flatMap { this.translate(it) })
|
||||
.flatMap { StubRenderer.render(it, shouldExportKDoc) + listOf("") }
|
||||
.flatMap { StubRenderer.render(it, shouldExportKDoc) + listOf("") }
|
||||
|
||||
File(outputFile).writeLines(lines)
|
||||
}
|
||||
+56
-55
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
|
||||
import org.jetbrains.kotlin.builtins.*
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.objcinterop.*
|
||||
import org.jetbrains.kotlin.ir.objcinterop.isObjCObjectType
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.resolve.DataClassResolver
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
||||
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
class ObjCExportMapper(
|
||||
internal val deprecationResolver: DeprecationResolver? = null,
|
||||
private val local: Boolean = false,
|
||||
internal val unitSuspendFunctionExport: UnitSuspendFunctionObjCExport
|
||||
internal val unitSuspendFunctionExport: UnitSuspendFunctionObjCExport,
|
||||
) {
|
||||
fun getCustomTypeMapper(descriptor: ClassDescriptor): CustomTypeMapper? = CustomTypeMappers.getMapper(descriptor)
|
||||
|
||||
@@ -38,7 +38,7 @@ class ObjCExportMapper(
|
||||
fun isSpecialMapped(descriptor: ClassDescriptor): Boolean {
|
||||
// TODO: this method duplicates some of the [ObjCExportTranslatorImpl.mapReferenceType] logic.
|
||||
return KotlinBuiltIns.isAny(descriptor) ||
|
||||
descriptor.getAllSuperClassifiers().any { it is ClassDescriptor && CustomTypeMappers.hasMapper(it) }
|
||||
descriptor.getAllSuperClassifiers().any { it is ClassDescriptor && CustomTypeMappers.hasMapper(it) }
|
||||
}
|
||||
|
||||
private val methodBridgeCache = mutableMapOf<FunctionDescriptor, MethodBridge>()
|
||||
@@ -122,13 +122,14 @@ internal fun ClassDescriptor.isHiddenFromObjC(): Boolean = when {
|
||||
}
|
||||
|
||||
internal fun ObjCExportMapper.shouldBeExposed(descriptor: ClassDescriptor): Boolean =
|
||||
shouldBeVisible(descriptor) && !isSpecialMapped(descriptor) && !descriptor.defaultType.isObjCObjectType()
|
||||
shouldBeVisible(descriptor) && !isSpecialMapped(descriptor) && !descriptor.defaultType.isObjCObjectType()
|
||||
|
||||
private fun ObjCExportMapper.isHiddenByDeprecation(descriptor: CallableMemberDescriptor): Boolean {
|
||||
// Note: ObjCExport generally expect overrides of exposed methods to be exposed.
|
||||
// So don't hide a "deprecated hidden" method which overrides non-hidden one:
|
||||
if (deprecationResolver != null && deprecationResolver.isDeprecatedHidden(descriptor) &&
|
||||
descriptor.overriddenDescriptors.all { isHiddenByDeprecation(it) }) {
|
||||
descriptor.overriddenDescriptors.all { isHiddenByDeprecation(it) }
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -185,14 +186,14 @@ private fun ObjCExportMapper.isHiddenByDeprecation(descriptor: ClassDescriptor):
|
||||
|
||||
// Note: the logic is partially duplicated in ObjCExportLazyImpl.translateClasses.
|
||||
internal fun ObjCExportMapper.shouldBeVisible(descriptor: ClassDescriptor): Boolean =
|
||||
descriptor.isEffectivelyPublicApi && when (descriptor.kind) {
|
||||
descriptor.isEffectivelyPublicApi && when (descriptor.kind) {
|
||||
ClassKind.CLASS, ClassKind.INTERFACE, ClassKind.ENUM_CLASS, ClassKind.OBJECT -> true
|
||||
ClassKind.ENUM_ENTRY, ClassKind.ANNOTATION_CLASS -> false
|
||||
} && !descriptor.isExpect && !descriptor.isInlined() && !isHiddenByDeprecation(descriptor) && !descriptor.isHiddenFromObjC()
|
||||
|
||||
private fun ObjCExportMapper.isBase(descriptor: CallableMemberDescriptor): Boolean =
|
||||
descriptor.overriddenDescriptors.all { !shouldBeExposed(it) }
|
||||
// e.g. it is not `override`, or overrides only unexposed methods.
|
||||
descriptor.overriddenDescriptors.all { !shouldBeExposed(it) }
|
||||
// e.g. it is not `override`, or overrides only unexposed methods.
|
||||
|
||||
/**
|
||||
* Check that given [descriptor] is a so-called "base method", i.e. method
|
||||
@@ -240,21 +241,21 @@ fun ObjCExportMapper.getBaseProperties(descriptor: PropertyDescriptor): List<Pro
|
||||
|
||||
@Suppress("NO_TAIL_CALLS_FOUND", "NON_TAIL_RECURSIVE_CALL") // K2 warning suppression, TODO: KT-62472
|
||||
internal tailrec fun KotlinType.getErasedTypeClass(): ClassDescriptor =
|
||||
TypeUtils.getClassDescriptor(this) ?: this.constructor.supertypes.first().getErasedTypeClass()
|
||||
TypeUtils.getClassDescriptor(this) ?: this.constructor.supertypes.first().getErasedTypeClass()
|
||||
|
||||
internal fun ObjCExportMapper.isTopLevel(descriptor: CallableMemberDescriptor): Boolean =
|
||||
descriptor.containingDeclaration !is ClassDescriptor && this.getClassIfCategory(descriptor) == null
|
||||
descriptor.containingDeclaration !is ClassDescriptor && this.getClassIfCategory(descriptor) == null
|
||||
|
||||
internal fun ObjCExportMapper.isObjCProperty(property: PropertyDescriptor): Boolean =
|
||||
property.extensionReceiverParameter == null || getClassIfCategory(property) != null
|
||||
property.extensionReceiverParameter == null || getClassIfCategory(property) != null
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
fun ClassDescriptor.getEnumValuesFunctionDescriptor(): SimpleFunctionDescriptor? {
|
||||
require(this.kind == ClassKind.ENUM_CLASS)
|
||||
|
||||
return this.staticScope.getContributedFunctions(
|
||||
StandardNames.ENUM_VALUES,
|
||||
NoLookupLocation.FROM_BACKEND
|
||||
StandardNames.ENUM_VALUES,
|
||||
NoLookupLocation.FROM_BACKEND
|
||||
).singleOrNull { it.extensionReceiverParameter == null && it.valueParameters.size == 0 }
|
||||
}
|
||||
|
||||
@@ -263,8 +264,8 @@ fun ClassDescriptor.getEnumEntriesPropertyDescriptor(): PropertyDescriptor? {
|
||||
require(this.kind == ClassKind.ENUM_CLASS)
|
||||
|
||||
return this.staticScope.getContributedVariables(
|
||||
StandardNames.ENUM_ENTRIES,
|
||||
NoLookupLocation.FROM_BACKEND
|
||||
StandardNames.ENUM_ENTRIES,
|
||||
NoLookupLocation.FROM_BACKEND
|
||||
).singleOrNull { it.extensionReceiverParameter == null }
|
||||
}
|
||||
|
||||
@@ -273,38 +274,38 @@ internal fun ObjCExportMapper.doesThrow(method: FunctionDescriptor): Boolean = m
|
||||
}
|
||||
|
||||
private fun ObjCExportMapper.bridgeType(
|
||||
kotlinType: KotlinType
|
||||
kotlinType: KotlinType,
|
||||
): TypeBridge = kotlinType.unwrapToPrimitiveOrReference<TypeBridge>(
|
||||
eachInlinedClass = { inlinedClass, _ ->
|
||||
when (inlinedClass.classId) {
|
||||
UnsignedType.UBYTE.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_CHAR)
|
||||
UnsignedType.USHORT.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_SHORT)
|
||||
UnsignedType.UINT.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_INT)
|
||||
UnsignedType.ULONG.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_LONG_LONG)
|
||||
}
|
||||
},
|
||||
ifPrimitive = { primitiveType, _ ->
|
||||
val objCValueType = when (primitiveType) {
|
||||
KonanPrimitiveType.BOOLEAN -> ObjCValueType.BOOL
|
||||
KonanPrimitiveType.CHAR -> ObjCValueType.UNICHAR
|
||||
KonanPrimitiveType.BYTE -> ObjCValueType.CHAR
|
||||
KonanPrimitiveType.SHORT -> ObjCValueType.SHORT
|
||||
KonanPrimitiveType.INT -> ObjCValueType.INT
|
||||
KonanPrimitiveType.LONG -> ObjCValueType.LONG_LONG
|
||||
KonanPrimitiveType.FLOAT -> ObjCValueType.FLOAT
|
||||
KonanPrimitiveType.DOUBLE -> ObjCValueType.DOUBLE
|
||||
KonanPrimitiveType.NON_NULL_NATIVE_PTR -> ObjCValueType.POINTER
|
||||
KonanPrimitiveType.VECTOR128 -> TODO()
|
||||
}
|
||||
ValueTypeBridge(objCValueType)
|
||||
},
|
||||
ifReference = {
|
||||
if (kotlinType.isFunctionType) {
|
||||
bridgeFunctionType(kotlinType)
|
||||
} else {
|
||||
ReferenceBridge
|
||||
}
|
||||
eachInlinedClass = { inlinedClass, _ ->
|
||||
when (inlinedClass.classId) {
|
||||
UnsignedType.UBYTE.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_CHAR)
|
||||
UnsignedType.USHORT.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_SHORT)
|
||||
UnsignedType.UINT.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_INT)
|
||||
UnsignedType.ULONG.classId -> return ValueTypeBridge(ObjCValueType.UNSIGNED_LONG_LONG)
|
||||
}
|
||||
},
|
||||
ifPrimitive = { primitiveType, _ ->
|
||||
val objCValueType = when (primitiveType) {
|
||||
KonanPrimitiveType.BOOLEAN -> ObjCValueType.BOOL
|
||||
KonanPrimitiveType.CHAR -> ObjCValueType.UNICHAR
|
||||
KonanPrimitiveType.BYTE -> ObjCValueType.CHAR
|
||||
KonanPrimitiveType.SHORT -> ObjCValueType.SHORT
|
||||
KonanPrimitiveType.INT -> ObjCValueType.INT
|
||||
KonanPrimitiveType.LONG -> ObjCValueType.LONG_LONG
|
||||
KonanPrimitiveType.FLOAT -> ObjCValueType.FLOAT
|
||||
KonanPrimitiveType.DOUBLE -> ObjCValueType.DOUBLE
|
||||
KonanPrimitiveType.NON_NULL_NATIVE_PTR -> ObjCValueType.POINTER
|
||||
KonanPrimitiveType.VECTOR128 -> TODO()
|
||||
}
|
||||
ValueTypeBridge(objCValueType)
|
||||
},
|
||||
ifReference = {
|
||||
if (kotlinType.isFunctionType) {
|
||||
bridgeFunctionType(kotlinType)
|
||||
} else {
|
||||
ReferenceBridge
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
private fun ObjCExportMapper.bridgeFunctionType(kotlinType: KotlinType): TypeBridge {
|
||||
@@ -323,8 +324,8 @@ private fun ObjCExportMapper.bridgeParameter(parameter: ParameterDescriptor): Me
|
||||
MethodBridgeValueParameter.Mapped(bridgeType(parameter.type))
|
||||
|
||||
private fun ObjCExportMapper.bridgeReturnType(
|
||||
descriptor: FunctionDescriptor,
|
||||
convertExceptionsToErrors: Boolean
|
||||
descriptor: FunctionDescriptor,
|
||||
convertExceptionsToErrors: Boolean,
|
||||
): MethodBridge.ReturnValue {
|
||||
val returnType = descriptor.returnType!!
|
||||
return when {
|
||||
@@ -343,7 +344,7 @@ private fun ObjCExportMapper.bridgeReturnType(
|
||||
}
|
||||
|
||||
descriptor.containingDeclaration.let { it is ClassDescriptor && KotlinBuiltIns.isAny(it) } &&
|
||||
descriptor.name.asString() == "hashCode" -> {
|
||||
descriptor.name.asString() == "hashCode" -> {
|
||||
assert(!convertExceptionsToErrors)
|
||||
MethodBridge.ReturnValue.HashCode
|
||||
}
|
||||
@@ -365,8 +366,8 @@ private fun ObjCExportMapper.bridgeReturnType(
|
||||
if (convertExceptionsToErrors) {
|
||||
val canReturnZero = !returnTypeBridge.isReferenceOrPointer() || TypeUtils.isNullableType(returnType)
|
||||
MethodBridge.ReturnValue.WithError.ZeroForError(
|
||||
successReturnValueBridge,
|
||||
successMayBeZero = canReturnZero
|
||||
successReturnValueBridge,
|
||||
successMayBeZero = canReturnZero
|
||||
)
|
||||
} else {
|
||||
successReturnValueBridge
|
||||
@@ -457,7 +458,7 @@ enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCTyp
|
||||
|
||||
// UNSIGNED_SHORT -> unsignedShort
|
||||
private val kindName = this.name.split('_')
|
||||
.joinToString("") { it.lowercase().replaceFirstChar(Char::uppercaseChar) }.replaceFirstChar(Char::lowercaseChar)
|
||||
.joinToString("") { it.lowercase().replaceFirstChar(Char::uppercaseChar) }.replaceFirstChar(Char::lowercaseChar)
|
||||
|
||||
|
||||
val valueSelector = kindName // unsignedShort
|
||||
@@ -465,13 +466,13 @@ enum class NSNumberKind(val mappedKotlinClassId: ClassId?, val objCType: ObjCTyp
|
||||
val factorySelector = "numberWith${kindName.replaceFirstChar(Char::uppercaseChar)}:" // numberWithUnsignedShort:
|
||||
|
||||
constructor(
|
||||
primitiveType: PrimitiveType,
|
||||
objCPrimitiveType: ObjCPrimitiveType
|
||||
primitiveType: PrimitiveType,
|
||||
objCPrimitiveType: ObjCPrimitiveType,
|
||||
) : this(ClassId.topLevel(primitiveType.typeFqName), objCPrimitiveType)
|
||||
|
||||
constructor(
|
||||
unsignedType: UnsignedType,
|
||||
objCPrimitiveType: ObjCPrimitiveType
|
||||
unsignedType: UnsignedType,
|
||||
objCPrimitiveType: ObjCPrimitiveType,
|
||||
) : this(unsignedType.classId, objCPrimitiveType)
|
||||
|
||||
constructor(objCPrimitiveType: ObjCPrimitiveType) : this(null, objCPrimitiveType)
|
||||
|
||||
+194
-173
@@ -39,7 +39,7 @@ internal interface ObjCExportNameTranslator {
|
||||
fun getCategoryName(file: KtFile): String
|
||||
|
||||
fun getClassOrProtocolName(
|
||||
ktClassOrObject: KtClassOrObject
|
||||
ktClassOrObject: KtClassOrObject,
|
||||
): ObjCExportNamer.ClassOrProtocolName
|
||||
|
||||
fun getTypeParameterName(ktTypeParameter: KtTypeParameter): String
|
||||
@@ -90,57 +90,61 @@ interface ObjCExportNamer {
|
||||
companion object {
|
||||
@InternalKotlinNativeApi
|
||||
const val kotlinThrowableAsErrorMethodName: String = "asError"
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
const val objectPropertyName: String = "shared"
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
const val companionObjectPropertyName: String = "companion"
|
||||
}
|
||||
}
|
||||
|
||||
fun createNamer(moduleDescriptor: ModuleDescriptor,
|
||||
topLevelNamePrefix: String): ObjCExportNamer =
|
||||
createNamer(moduleDescriptor, emptyList(), topLevelNamePrefix)
|
||||
fun createNamer(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
topLevelNamePrefix: String,
|
||||
): ObjCExportNamer =
|
||||
createNamer(moduleDescriptor, emptyList(), topLevelNamePrefix)
|
||||
|
||||
fun createNamer(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
exportedDependencies: List<ModuleDescriptor>,
|
||||
topLevelNamePrefix: String
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
exportedDependencies: List<ModuleDescriptor>,
|
||||
topLevelNamePrefix: String,
|
||||
): ObjCExportNamer = ObjCExportNamerImpl(
|
||||
(exportedDependencies + moduleDescriptor).toSet(),
|
||||
moduleDescriptor.builtIns,
|
||||
ObjCExportMapper(local = true, unitSuspendFunctionExport = UnitSuspendFunctionObjCExport.DEFAULT),
|
||||
ObjCExportProblemCollector.SILENT,
|
||||
topLevelNamePrefix,
|
||||
local = true
|
||||
(exportedDependencies + moduleDescriptor).toSet(),
|
||||
moduleDescriptor.builtIns,
|
||||
ObjCExportMapper(local = true, unitSuspendFunctionExport = UnitSuspendFunctionObjCExport.DEFAULT),
|
||||
ObjCExportProblemCollector.SILENT,
|
||||
topLevelNamePrefix,
|
||||
local = true
|
||||
)
|
||||
|
||||
// Note: this class duplicates some of ObjCExportNamerImpl logic,
|
||||
// but operates on different representation.
|
||||
internal open class ObjCExportNameTranslatorImpl(
|
||||
private val configuration: ObjCExportNamer.Configuration
|
||||
private val configuration: ObjCExportNamer.Configuration,
|
||||
) : ObjCExportNameTranslator {
|
||||
|
||||
private val helper = ObjCExportNamingHelper(configuration.topLevelNamePrefix, configuration.objcGenerics)
|
||||
|
||||
override fun getFileClassName(file: KtFile): ObjCExportNamer.ClassOrProtocolName =
|
||||
helper.getFileClassName(file)
|
||||
helper.getFileClassName(file)
|
||||
|
||||
override fun getCategoryName(file: KtFile): String =
|
||||
helper.translateFileName(file)
|
||||
helper.translateFileName(file)
|
||||
|
||||
override fun getClassOrProtocolName(ktClassOrObject: KtClassOrObject): ObjCExportNamer.ClassOrProtocolName =
|
||||
ObjCExportNamer.ClassOrProtocolName(
|
||||
swiftName = getClassOrProtocolAsSwiftName(ktClassOrObject, true),
|
||||
objCName = buildString {
|
||||
getClassOrProtocolAsSwiftName(ktClassOrObject, false).split('.').forEachIndexed { index, part ->
|
||||
append(if (index == 0) part else part.replaceFirstChar(Char::uppercaseChar))
|
||||
}
|
||||
}
|
||||
)
|
||||
ObjCExportNamer.ClassOrProtocolName(
|
||||
swiftName = getClassOrProtocolAsSwiftName(ktClassOrObject, true),
|
||||
objCName = buildString {
|
||||
getClassOrProtocolAsSwiftName(ktClassOrObject, false).split('.').forEachIndexed { index, part ->
|
||||
append(if (index == 0) part else part.replaceFirstChar(Char::uppercaseChar))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
private fun getClassOrProtocolAsSwiftName(
|
||||
ktClassOrObject: KtClassOrObject,
|
||||
forSwift: Boolean
|
||||
ktClassOrObject: KtClassOrObject,
|
||||
forSwift: Boolean,
|
||||
): String = buildString {
|
||||
val objCName = ktClassOrObject.getObjCName()
|
||||
if (objCName.isExact) {
|
||||
@@ -157,20 +161,20 @@ internal open class ObjCExportNameTranslatorImpl(
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendNameWithContainer(
|
||||
ktClassOrObject: KtClassOrObject,
|
||||
objCName: ObjCName,
|
||||
outerClass: KtClassOrObject,
|
||||
forSwift: Boolean
|
||||
ktClassOrObject: KtClassOrObject,
|
||||
objCName: ObjCName,
|
||||
outerClass: KtClassOrObject,
|
||||
forSwift: Boolean,
|
||||
) = helper.appendNameWithContainer(
|
||||
this,
|
||||
ktClassOrObject, objCName.asIdentifier(forSwift),
|
||||
outerClass, getClassOrProtocolAsSwiftName(outerClass, forSwift),
|
||||
object : ObjCExportNamingHelper.ClassInfoProvider<KtClassOrObject> {
|
||||
override fun hasGenerics(clazz: KtClassOrObject): Boolean =
|
||||
clazz.typeParametersWithOuter.count() != 0
|
||||
this,
|
||||
ktClassOrObject, objCName.asIdentifier(forSwift),
|
||||
outerClass, getClassOrProtocolAsSwiftName(outerClass, forSwift),
|
||||
object : ObjCExportNamingHelper.ClassInfoProvider<KtClassOrObject> {
|
||||
override fun hasGenerics(clazz: KtClassOrObject): Boolean =
|
||||
clazz.typeParametersWithOuter.count() != 0
|
||||
|
||||
override fun isInterface(clazz: KtClassOrObject): Boolean = ktClassOrObject.isInterface
|
||||
}
|
||||
override fun isInterface(clazz: KtClassOrObject): Boolean = ktClassOrObject.isInterface
|
||||
}
|
||||
)
|
||||
|
||||
override fun getTypeParameterName(ktTypeParameter: KtTypeParameter): String = buildString {
|
||||
@@ -180,12 +184,12 @@ internal open class ObjCExportNameTranslatorImpl(
|
||||
}
|
||||
|
||||
private class ObjCExportNamingHelper(
|
||||
private val topLevelNamePrefix: String,
|
||||
private val objcGenerics: Boolean
|
||||
private val topLevelNamePrefix: String,
|
||||
private val objcGenerics: Boolean,
|
||||
) {
|
||||
|
||||
fun translateFileName(fileName: String): String =
|
||||
PackagePartClassUtils.getFilePartShortName(fileName).toIdentifier()
|
||||
PackagePartClassUtils.getFilePartShortName(fileName).toIdentifier()
|
||||
|
||||
fun translateFileName(file: KtFile): String = translateFileName(file.name)
|
||||
|
||||
@@ -195,15 +199,15 @@ private class ObjCExportNamingHelper(
|
||||
}
|
||||
|
||||
fun getFileClassName(file: KtFile): ObjCExportNamer.ClassOrProtocolName =
|
||||
getFileClassName(file.name)
|
||||
getFileClassName(file.name)
|
||||
|
||||
fun <T> appendNameWithContainer(
|
||||
builder: StringBuilder,
|
||||
clazz: T,
|
||||
ownName: String,
|
||||
containingClass: T,
|
||||
containerName: String,
|
||||
provider: ClassInfoProvider<T>
|
||||
builder: StringBuilder,
|
||||
clazz: T,
|
||||
ownName: String,
|
||||
containingClass: T,
|
||||
containerName: String,
|
||||
provider: ClassInfoProvider<T>,
|
||||
) = builder.apply {
|
||||
if (clazz.canBeSwiftInner(provider)) {
|
||||
append(containerName)
|
||||
@@ -271,54 +275,56 @@ private class ObjCExportNamingHelper(
|
||||
|
||||
fun isTypeParameterNameReserved(name: String): Boolean = name in reservedTypeParameterNames
|
||||
|
||||
private val reservedTypeParameterNames = setOf("id", "NSObject", "NSArray", "NSCopying", "NSNumber", "NSInteger",
|
||||
"NSUInteger", "NSString", "NSSet", "NSDictionary", "NSMutableArray", "int", "unsigned", "short",
|
||||
"char", "long", "float", "double", "int32_t", "int64_t", "int16_t", "int8_t", "unichar")
|
||||
private val reservedTypeParameterNames = setOf(
|
||||
"id", "NSObject", "NSArray", "NSCopying", "NSNumber", "NSInteger",
|
||||
"NSUInteger", "NSString", "NSSet", "NSDictionary", "NSMutableArray", "int", "unsigned", "short",
|
||||
"char", "long", "float", "double", "int32_t", "int64_t", "int16_t", "int8_t", "unichar"
|
||||
)
|
||||
}
|
||||
|
||||
@InternalKotlinNativeApi
|
||||
class ObjCExportNamerImpl(
|
||||
private val configuration: ObjCExportNamer.Configuration,
|
||||
builtIns: KotlinBuiltIns,
|
||||
private val mapper: ObjCExportMapper,
|
||||
private val problemCollector: ObjCExportProblemCollector,
|
||||
private val local: Boolean
|
||||
private val configuration: ObjCExportNamer.Configuration,
|
||||
builtIns: KotlinBuiltIns,
|
||||
private val mapper: ObjCExportMapper,
|
||||
private val problemCollector: ObjCExportProblemCollector,
|
||||
private val local: Boolean,
|
||||
) : ObjCExportNamer {
|
||||
constructor(
|
||||
moduleDescriptors: Set<ModuleDescriptor>,
|
||||
builtIns: KotlinBuiltIns,
|
||||
mapper: ObjCExportMapper,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
topLevelNamePrefix: String,
|
||||
local: Boolean,
|
||||
objcGenerics: Boolean = false,
|
||||
disableSwiftMemberNameMangling: Boolean = false,
|
||||
ignoreInterfaceMethodCollisions: Boolean = false,
|
||||
reportNameCollisions: Boolean = false,
|
||||
moduleDescriptors: Set<ModuleDescriptor>,
|
||||
builtIns: KotlinBuiltIns,
|
||||
mapper: ObjCExportMapper,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
topLevelNamePrefix: String,
|
||||
local: Boolean,
|
||||
objcGenerics: Boolean = false,
|
||||
disableSwiftMemberNameMangling: Boolean = false,
|
||||
ignoreInterfaceMethodCollisions: Boolean = false,
|
||||
reportNameCollisions: Boolean = false,
|
||||
) : this(
|
||||
object : ObjCExportNamer.Configuration {
|
||||
override val topLevelNamePrefix: String
|
||||
get() = topLevelNamePrefix
|
||||
object : ObjCExportNamer.Configuration {
|
||||
override val topLevelNamePrefix: String
|
||||
get() = topLevelNamePrefix
|
||||
|
||||
override fun getAdditionalPrefix(module: ModuleDescriptor): String? =
|
||||
if (module in moduleDescriptors) null else module.objCExportAdditionalNamePrefix
|
||||
override fun getAdditionalPrefix(module: ModuleDescriptor): String? =
|
||||
if (module in moduleDescriptors) null else module.objCExportAdditionalNamePrefix
|
||||
|
||||
override val objcGenerics: Boolean
|
||||
get() = objcGenerics
|
||||
override val objcGenerics: Boolean
|
||||
get() = objcGenerics
|
||||
|
||||
override val disableSwiftMemberNameMangling: Boolean
|
||||
get() = disableSwiftMemberNameMangling
|
||||
override val disableSwiftMemberNameMangling: Boolean
|
||||
get() = disableSwiftMemberNameMangling
|
||||
|
||||
override val ignoreInterfaceMethodCollisions: Boolean
|
||||
get() = ignoreInterfaceMethodCollisions
|
||||
override val ignoreInterfaceMethodCollisions: Boolean
|
||||
get() = ignoreInterfaceMethodCollisions
|
||||
|
||||
override val reportNameCollisions: Boolean
|
||||
get() = reportNameCollisions
|
||||
},
|
||||
builtIns,
|
||||
mapper,
|
||||
problemCollector,
|
||||
local
|
||||
override val reportNameCollisions: Boolean
|
||||
get() = reportNameCollisions
|
||||
},
|
||||
builtIns,
|
||||
mapper,
|
||||
problemCollector,
|
||||
local
|
||||
)
|
||||
|
||||
private val objcGenerics get() = configuration.objcGenerics
|
||||
@@ -326,8 +332,8 @@ class ObjCExportNamerImpl(
|
||||
private val helper = ObjCExportNamingHelper(configuration.topLevelNamePrefix, objcGenerics)
|
||||
|
||||
private fun String.toSpecialStandardClassOrProtocolName() = ObjCExportNamer.ClassOrProtocolName(
|
||||
swiftName = "Kotlin$this",
|
||||
objCName = "${topLevelNamePrefix}$this"
|
||||
swiftName = "Kotlin$this",
|
||||
objCName = "${topLevelNamePrefix}$this"
|
||||
)
|
||||
|
||||
override val kotlinAnyName = "Base".toSpecialStandardClassOrProtocolName()
|
||||
@@ -336,7 +342,7 @@ class ObjCExportNamerImpl(
|
||||
override val mutableMapName = "MutableDictionary".toSpecialStandardClassOrProtocolName()
|
||||
|
||||
override fun numberBoxName(classId: ClassId): ObjCExportNamer.ClassOrProtocolName =
|
||||
classId.shortClassName.asString().toSpecialStandardClassOrProtocolName()
|
||||
classId.shortClassName.asString().toSpecialStandardClassOrProtocolName()
|
||||
|
||||
override val kotlinNumberName = "Number".toSpecialStandardClassOrProtocolName()
|
||||
|
||||
@@ -345,15 +351,15 @@ class ObjCExportNamerImpl(
|
||||
// Try to avoid clashing with critical NSObject instance methods:
|
||||
|
||||
private val reserved = setOf(
|
||||
"retain", "release", "autorelease",
|
||||
"class", "superclass",
|
||||
"hash"
|
||||
"retain", "release", "autorelease",
|
||||
"class", "superclass",
|
||||
"hash"
|
||||
)
|
||||
|
||||
override fun reserved(name: String) = name in reserved
|
||||
|
||||
override fun conflict(first: FunctionDescriptor, second: FunctionDescriptor): Boolean =
|
||||
!mapper.canHaveSameSelector(first, second, configuration.ignoreInterfaceMethodCollisions)
|
||||
!mapper.canHaveSameSelector(first, second, configuration.ignoreInterfaceMethodCollisions)
|
||||
}
|
||||
|
||||
private val methodSwiftNames = object : Mapping<FunctionDescriptor, String>() {
|
||||
@@ -393,11 +399,11 @@ class ObjCExportNamerImpl(
|
||||
// Try to avoid clashing with NSObject class methods:
|
||||
|
||||
private val reserved = setOf(
|
||||
"retain", "release", "autorelease",
|
||||
"initialize", "load", "alloc", "new", "class", "superclass",
|
||||
"classFallbacksForKeyedArchiver", "classForKeyedUnarchiver",
|
||||
"description", "debugDescription", "version", "hash",
|
||||
"useStoredAccessor"
|
||||
"retain", "release", "autorelease",
|
||||
"initialize", "load", "alloc", "new", "class", "superclass",
|
||||
"classFallbacksForKeyedArchiver", "classForKeyedUnarchiver",
|
||||
"description", "debugDescription", "version", "hash",
|
||||
"useStoredAccessor"
|
||||
)
|
||||
|
||||
override fun reserved(name: String) = (name in reserved) || (name in cKeywords)
|
||||
@@ -409,7 +415,7 @@ class ObjCExportNamerImpl(
|
||||
|
||||
private inner class EnumNameMapping : ClassSelectorNameMapping<DeclarationDescriptor>() {
|
||||
override fun conflict(first: DeclarationDescriptor, second: DeclarationDescriptor) =
|
||||
first.containingDeclaration == second.containingDeclaration
|
||||
first.containingDeclaration == second.containingDeclaration
|
||||
}
|
||||
|
||||
private val enumClassSelectors = EnumNameMapping()
|
||||
@@ -440,13 +446,13 @@ class ObjCExportNamerImpl(
|
||||
}
|
||||
|
||||
override fun getClassOrProtocolName(descriptor: ClassDescriptor): ObjCExportNamer.ClassOrProtocolName =
|
||||
ObjCExportNamer.ClassOrProtocolName(
|
||||
swiftName = getClassOrProtocolSwiftName(descriptor),
|
||||
objCName = getClassOrProtocolObjCName(descriptor)
|
||||
)
|
||||
ObjCExportNamer.ClassOrProtocolName(
|
||||
swiftName = getClassOrProtocolSwiftName(descriptor),
|
||||
objCName = getClassOrProtocolObjCName(descriptor)
|
||||
)
|
||||
|
||||
private fun getClassOrProtocolSwiftName(
|
||||
descriptor: ClassDescriptor
|
||||
descriptor: ClassDescriptor,
|
||||
): String = swiftClassAndProtocolNames.getOrPut(descriptor) {
|
||||
StringBuilder().apply {
|
||||
val objCName = descriptor.getObjCName()
|
||||
@@ -466,19 +472,19 @@ class ObjCExportNamerImpl(
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendSwiftNameWithContainer(
|
||||
clazz: ClassDescriptor,
|
||||
objCName: ObjCName,
|
||||
containingClass: ClassDescriptor
|
||||
clazz: ClassDescriptor,
|
||||
objCName: ObjCName,
|
||||
containingClass: ClassDescriptor,
|
||||
) = helper.appendNameWithContainer(
|
||||
this,
|
||||
clazz, objCName.asIdentifier(true),
|
||||
containingClass, getClassOrProtocolSwiftName(containingClass),
|
||||
object : ObjCExportNamingHelper.ClassInfoProvider<ClassDescriptor> {
|
||||
override fun hasGenerics(clazz: ClassDescriptor): Boolean =
|
||||
clazz.typeConstructor.parameters.isNotEmpty()
|
||||
this,
|
||||
clazz, objCName.asIdentifier(true),
|
||||
containingClass, getClassOrProtocolSwiftName(containingClass),
|
||||
object : ObjCExportNamingHelper.ClassInfoProvider<ClassDescriptor> {
|
||||
override fun hasGenerics(clazz: ClassDescriptor): Boolean =
|
||||
clazz.typeConstructor.parameters.isNotEmpty()
|
||||
|
||||
override fun isInterface(clazz: ClassDescriptor): Boolean = clazz.isInterface
|
||||
}
|
||||
override fun isInterface(clazz: ClassDescriptor): Boolean = clazz.isInterface
|
||||
}
|
||||
)
|
||||
|
||||
private fun getClassOrProtocolObjCName(descriptor: ClassDescriptor): String {
|
||||
@@ -492,7 +498,7 @@ class ObjCExportNamerImpl(
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
if (containingDeclaration is ClassDescriptor) {
|
||||
append(getClassOrProtocolObjCName(containingDeclaration))
|
||||
.append(objCName.asIdentifier(false).replaceFirstChar(Char::uppercaseChar))
|
||||
.append(objCName.asIdentifier(false).replaceFirstChar(Char::uppercaseChar))
|
||||
} else if (containingDeclaration is PackageFragmentDescriptor) {
|
||||
append(topLevelNamePrefix).appendTopLevelClassBaseName(descriptor, objCName, false)
|
||||
} else {
|
||||
@@ -537,12 +543,14 @@ class ObjCExportNamerImpl(
|
||||
}
|
||||
|
||||
if (index == 0) {
|
||||
append(when {
|
||||
bridge is MethodBridgeValueParameter.ErrorOutParameter -> "AndReturn"
|
||||
bridge is MethodBridgeValueParameter.SuspendCompletion -> "With"
|
||||
method is ConstructorDescriptor -> "With"
|
||||
else -> ""
|
||||
})
|
||||
append(
|
||||
when {
|
||||
bridge is MethodBridgeValueParameter.ErrorOutParameter -> "AndReturn"
|
||||
bridge is MethodBridgeValueParameter.SuspendCompletion -> "With"
|
||||
method is ConstructorDescriptor -> "With"
|
||||
else -> ""
|
||||
}
|
||||
)
|
||||
append(name.replaceFirstChar(Char::uppercaseChar))
|
||||
} else {
|
||||
append(name)
|
||||
@@ -618,8 +626,8 @@ class ObjCExportNamerImpl(
|
||||
}
|
||||
}
|
||||
return ObjCExportNamer.PropertyName(
|
||||
swiftName = swiftPropertyNames.getOrPut(true),
|
||||
objCName = objCPropertyNames.getOrPut(false)
|
||||
swiftName = swiftPropertyNames.getOrPut(true),
|
||||
objCName = objCPropertyNames.getOrPut(false)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -628,7 +636,7 @@ class ObjCExportNamerImpl(
|
||||
|
||||
return objectInstanceSelectors.getOrPut(descriptor) {
|
||||
val name = descriptor.getObjCName().asString(false)
|
||||
.replaceFirstChar(Char::lowercaseChar).toIdentifier().mangleIfSpecialFamily("get")
|
||||
.replaceFirstChar(Char::lowercaseChar).toIdentifier().mangleIfSpecialFamily("get")
|
||||
StringBuilder(name).mangledBySuffixUnderscores()
|
||||
}
|
||||
}
|
||||
@@ -701,9 +709,9 @@ class ObjCExportNamerImpl(
|
||||
val any = builtIns.any
|
||||
|
||||
val predefinedClassNames = mapOf(
|
||||
builtIns.any to kotlinAnyName,
|
||||
builtIns.mutableSet to mutableSetName,
|
||||
builtIns.mutableMap to mutableMapName
|
||||
builtIns.any to kotlinAnyName,
|
||||
builtIns.mutableSet to mutableSetName,
|
||||
builtIns.mutableMap to mutableMapName
|
||||
)
|
||||
|
||||
predefinedClassNames.forEach { (descriptor, name) ->
|
||||
@@ -712,10 +720,10 @@ class ObjCExportNamerImpl(
|
||||
}
|
||||
|
||||
fun ClassDescriptor.method(name: Name) =
|
||||
this.unsubstitutedMemberScope.getContributedFunctions(
|
||||
name,
|
||||
NoLookupLocation.FROM_BACKEND
|
||||
).single()
|
||||
this.unsubstitutedMemberScope.getContributedFunctions(
|
||||
name,
|
||||
NoLookupLocation.FROM_BACKEND
|
||||
).single()
|
||||
|
||||
Predefined.anyMethodSelectors.forEach { (name, selector) ->
|
||||
methodSelectors.forceAssign(any.method(name), selector)
|
||||
@@ -728,21 +736,21 @@ class ObjCExportNamerImpl(
|
||||
|
||||
private object Predefined {
|
||||
val anyMethodSelectors = mapOf(
|
||||
"hashCode" to "hash",
|
||||
"toString" to "description",
|
||||
"equals" to "isEqual:"
|
||||
"hashCode" to "hash",
|
||||
"toString" to "description",
|
||||
"equals" to "isEqual:"
|
||||
).mapKeys { Name.identifier(it.key) }
|
||||
|
||||
val anyMethodSwiftNames = mapOf(
|
||||
"hashCode" to "hash()",
|
||||
"toString" to "description()",
|
||||
"equals" to "isEqual(_:)"
|
||||
"hashCode" to "hash()",
|
||||
"toString" to "description()",
|
||||
"equals" to "isEqual(_:)"
|
||||
).mapKeys { Name.identifier(it.key) }
|
||||
}
|
||||
|
||||
private object Reserved {
|
||||
val propertyNames = cKeywords +
|
||||
setOf("description") // https://youtrack.jetbrains.com/issue/KT-38641
|
||||
setOf("description") // https://youtrack.jetbrains.com/issue/KT-38641
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.getMangledName(forSwift: Boolean): String {
|
||||
@@ -777,7 +785,7 @@ class ObjCExportNamerImpl(
|
||||
}
|
||||
|
||||
private fun String.startsWithWords(words: String) = this.startsWith(words) &&
|
||||
(this.length == words.length || !this[words.length].isLowerCase())
|
||||
(this.length == words.length || !this[words.length].isLowerCase())
|
||||
|
||||
private inner class GenericTypeParameterNameMapping {
|
||||
private val elementToName = mutableMapOf<TypeParameterDescriptor, String>()
|
||||
@@ -818,7 +826,7 @@ class ObjCExportNamerImpl(
|
||||
assert(element.containingDeclaration is ClassDescriptor)
|
||||
|
||||
return !objCClassNames.nameExists(name) && !objCProtocolNames.nameExists(name) &&
|
||||
(local || name !in classNameSet(element))
|
||||
(local || name !in classNameSet(element))
|
||||
}
|
||||
|
||||
private fun classNameSet(element: TypeParameterDescriptor): MutableSet<String> {
|
||||
@@ -893,14 +901,18 @@ class ObjCExportNamerImpl(
|
||||
}
|
||||
|
||||
private inline fun StringBuilder.mangledSequence(crossinline mangle: StringBuilder.() -> Unit) =
|
||||
generateSequence(this.toString()) {
|
||||
this@mangledSequence.mangle()
|
||||
this@mangledSequence.toString()
|
||||
}
|
||||
generateSequence(this.toString()) {
|
||||
this@mangledSequence.mangle()
|
||||
this@mangledSequence.toString()
|
||||
}
|
||||
|
||||
private fun StringBuilder.mangledBySuffixUnderscores() = this.mangledSequence { append("_") }
|
||||
|
||||
private fun ObjCExportMapper.canHaveCommonSubtype(first: ClassDescriptor, second: ClassDescriptor, ignoreInterfaceMethodCollisions: Boolean): Boolean {
|
||||
private fun ObjCExportMapper.canHaveCommonSubtype(
|
||||
first: ClassDescriptor,
|
||||
second: ClassDescriptor,
|
||||
ignoreInterfaceMethodCollisions: Boolean,
|
||||
): Boolean {
|
||||
if (first.isSubclassOf(second) || second.isSubclassOf(first)) {
|
||||
return true
|
||||
}
|
||||
@@ -913,13 +925,13 @@ private fun ObjCExportMapper.canHaveCommonSubtype(first: ClassDescriptor, second
|
||||
}
|
||||
|
||||
private fun ObjCExportMapper.canBeInheritedBySameClass(
|
||||
first: CallableMemberDescriptor,
|
||||
second: CallableMemberDescriptor,
|
||||
ignoreInterfaceMethodCollisions: Boolean
|
||||
first: CallableMemberDescriptor,
|
||||
second: CallableMemberDescriptor,
|
||||
ignoreInterfaceMethodCollisions: Boolean,
|
||||
): Boolean {
|
||||
if (this.isTopLevel(first) || this.isTopLevel(second)) {
|
||||
return this.isTopLevel(first) && this.isTopLevel(second) &&
|
||||
first.propertyIfAccessor.findSourceFile() == second.propertyIfAccessor.findSourceFile()
|
||||
first.propertyIfAccessor.findSourceFile() == second.propertyIfAccessor.findSourceFile()
|
||||
}
|
||||
|
||||
val firstClass = this.getClassIfCategory(first) ?: first.containingDeclaration as ClassDescriptor
|
||||
@@ -936,7 +948,11 @@ private fun ObjCExportMapper.canBeInheritedBySameClass(
|
||||
return canHaveCommonSubtype(firstClass, secondClass, ignoreInterfaceMethodCollisions)
|
||||
}
|
||||
|
||||
private fun ObjCExportMapper.canHaveSameSelector(first: FunctionDescriptor, second: FunctionDescriptor, ignoreInterfaceMethodCollisions: Boolean): Boolean {
|
||||
private fun ObjCExportMapper.canHaveSameSelector(
|
||||
first: FunctionDescriptor,
|
||||
second: FunctionDescriptor,
|
||||
ignoreInterfaceMethodCollisions: Boolean,
|
||||
): Boolean {
|
||||
assert(isBaseMethod(first))
|
||||
assert(isBaseMethod(second))
|
||||
|
||||
@@ -968,7 +984,11 @@ private fun ObjCExportMapper.canHaveSameSelector(first: FunctionDescriptor, seco
|
||||
return bridgeMethod(first) == bridgeMethod(second)
|
||||
}
|
||||
|
||||
private fun ObjCExportMapper.canHaveSameName(first: PropertyDescriptor, second: PropertyDescriptor, ignoreInterfaceMethodCollisions: Boolean): Boolean {
|
||||
private fun ObjCExportMapper.canHaveSameName(
|
||||
first: PropertyDescriptor,
|
||||
second: PropertyDescriptor,
|
||||
ignoreInterfaceMethodCollisions: Boolean,
|
||||
): Boolean {
|
||||
assert(isBaseProperty(first))
|
||||
assert(isObjCProperty(first))
|
||||
assert(isBaseProperty(second))
|
||||
@@ -991,17 +1011,17 @@ private fun ObjCExportMapper.canHaveSameName(first: PropertyDescriptor, second:
|
||||
}
|
||||
|
||||
private class ObjCName(
|
||||
private val kotlinName: String,
|
||||
private val objCName: String?,
|
||||
private val swiftName: String?,
|
||||
val isExact: Boolean
|
||||
private val kotlinName: String,
|
||||
private val objCName: String?,
|
||||
private val swiftName: String?,
|
||||
val isExact: Boolean,
|
||||
) {
|
||||
// TODO: Prevent mangling when objCName or swiftName is provided
|
||||
|
||||
fun asString(forSwift: Boolean): String = swiftName.takeIf { forSwift } ?: objCName ?: kotlinName
|
||||
|
||||
fun asIdentifier(forSwift: Boolean, default: (String) -> String = { it.toIdentifier() }): String =
|
||||
swiftName.takeIf { forSwift } ?: objCName ?: default(kotlinName)
|
||||
swiftName.takeIf { forSwift } ?: objCName ?: default(kotlinName)
|
||||
}
|
||||
|
||||
private fun DeclarationDescriptor.getObjCName(): ObjCName {
|
||||
@@ -1019,7 +1039,7 @@ private fun DeclarationDescriptor.getObjCName(): ObjCName {
|
||||
private fun <T> T.upcast(): T = this
|
||||
|
||||
private fun CallableDescriptor.getObjCName(): ObjCName =
|
||||
overriddenDescriptors.firstOrNull()?.getObjCName() ?: upcast<DeclarationDescriptor>().getObjCName()
|
||||
overriddenDescriptors.firstOrNull()?.getObjCName() ?: upcast<DeclarationDescriptor>().getObjCName()
|
||||
|
||||
private fun ParameterDescriptor.getObjCName(): ObjCName {
|
||||
val callableDescriptor = containingDeclaration as? CallableDescriptor ?: return upcast<CallableDescriptor>().getObjCName()
|
||||
@@ -1053,7 +1073,7 @@ private fun KtClassOrObject.getObjCName(): ObjCName {
|
||||
}
|
||||
|
||||
fun ValueArgument.getBooleanValue(): Boolean =
|
||||
(getArgumentExpression() as? KtConstantExpression)?.text?.toBooleanStrictOrNull() ?: false
|
||||
(getArgumentExpression() as? KtConstantExpression)?.text?.toBooleanStrictOrNull() ?: false
|
||||
|
||||
val argNames = setOf("name", "swiftName", "exact")
|
||||
val processedArgs = mutableSetOf<String>()
|
||||
@@ -1070,26 +1090,27 @@ private fun KtClassOrObject.getObjCName(): ObjCName {
|
||||
return ObjCName(name!!, objCName, swiftName, isExact)
|
||||
}
|
||||
|
||||
internal val ModuleDescriptor.objCExportAdditionalNamePrefix: String get() {
|
||||
if (this.isNativeStdlib()) return "Kotlin"
|
||||
internal val ModuleDescriptor.objCExportAdditionalNamePrefix: String
|
||||
get() {
|
||||
if (this.isNativeStdlib()) return "Kotlin"
|
||||
|
||||
val fullPrefix = when(val module = this.klibModuleOrigin) {
|
||||
CurrentKlibModuleOrigin ->
|
||||
error("expected deserialized module, got $this (origin = $module)")
|
||||
SyntheticModulesOrigin ->
|
||||
this.name.asString().let { it.substring(1, it.lastIndex) }
|
||||
is DeserializedKlibModuleOrigin ->
|
||||
module.library.let { it.shortName ?: it.uniqueName }
|
||||
val fullPrefix = when (val module = this.klibModuleOrigin) {
|
||||
CurrentKlibModuleOrigin ->
|
||||
error("expected deserialized module, got $this (origin = $module)")
|
||||
SyntheticModulesOrigin ->
|
||||
this.name.asString().let { it.substring(1, it.lastIndex) }
|
||||
is DeserializedKlibModuleOrigin ->
|
||||
module.library.let { it.shortName ?: it.uniqueName }
|
||||
}
|
||||
|
||||
return abbreviate(fullPrefix)
|
||||
}
|
||||
|
||||
return abbreviate(fullPrefix)
|
||||
}
|
||||
|
||||
|
||||
fun abbreviate(name: String): String {
|
||||
val normalizedName = name
|
||||
.replaceFirstChar(Char::uppercaseChar)
|
||||
.replace("-|\\.".toRegex(), "_")
|
||||
.replaceFirstChar(Char::uppercaseChar)
|
||||
.replace("-|\\.".toRegex(), "_")
|
||||
|
||||
val uppers = normalizedName.filterIndexed { index, character -> index == 0 || character.isUpperCase() }
|
||||
if (uppers.length >= 3) return uppers
|
||||
@@ -1104,8 +1125,8 @@ internal fun String.toValidObjCSwiftIdentifier(): String {
|
||||
if (this.isEmpty()) return "__"
|
||||
|
||||
return this.replace('$', '_') // TODO: handle more special characters.
|
||||
.let { if (it.first().isDigit()) "_$it" else it }
|
||||
.let { if (it == "_") "__" else it }
|
||||
.let { if (it.first().isDigit()) "_$it" else it }
|
||||
.let { if (it == "_") "__" else it }
|
||||
}
|
||||
|
||||
// Private shortcut.
|
||||
|
||||
+9
-9
@@ -22,7 +22,7 @@ interface ObjCExportScope {
|
||||
|
||||
fun deriveForType(kotlinType: KotlinType): ObjCTypeExportScope = ObjCTypeExportScopeImpl(kotlinType, this)
|
||||
fun deriveForClass(container: DeclarationDescriptor, namer: ObjCExportNamer): ObjCClassExportScope =
|
||||
ObjCClassExportScopeImpl(container, namer, this)
|
||||
ObjCClassExportScopeImpl(container, namer, this)
|
||||
}
|
||||
|
||||
internal inline fun <reified T : ObjCExportScope> ObjCExportScope.nearestScopeOfType(): T? {
|
||||
@@ -44,16 +44,16 @@ interface ObjCClassExportScope : ObjCExportScope {
|
||||
}
|
||||
|
||||
private class ObjCClassExportScopeImpl constructor(
|
||||
container: DeclarationDescriptor,
|
||||
val namer: ObjCExportNamer,
|
||||
override val parent: ObjCExportScope?,
|
||||
container: DeclarationDescriptor,
|
||||
val namer: ObjCExportNamer,
|
||||
override val parent: ObjCExportScope?,
|
||||
) : ObjCClassExportScope {
|
||||
private val typeParameterNames: List<TypeParameterDescriptor> =
|
||||
if (container is ClassDescriptor && !container.isInterface) {
|
||||
container.typeConstructor.parameters
|
||||
} else {
|
||||
emptyList<TypeParameterDescriptor>()
|
||||
}
|
||||
if (container is ClassDescriptor && !container.isInterface) {
|
||||
container.typeConstructor.parameters
|
||||
} else {
|
||||
emptyList<TypeParameterDescriptor>()
|
||||
}
|
||||
|
||||
override fun getGenericTypeUsage(typeParameterDescriptor: TypeParameterDescriptor?): ObjCGenericTypeUsage? {
|
||||
return typeParameterDescriptor?.let { descriptor ->
|
||||
|
||||
+9
-1
@@ -12,7 +12,15 @@ class ObjCExportTranslatorMobile internal constructor(private val delegate: ObjC
|
||||
companion object {
|
||||
fun create(namer: ObjCExportNamer, configuration: ObjCExportLazy.Configuration): ObjCExportTranslatorMobile {
|
||||
val mapper = ObjCExportMapper(local = true, unitSuspendFunctionExport = configuration.unitSuspendFunctionExport)
|
||||
return ObjCExportTranslatorMobile(ObjCExportTranslatorImpl(null, mapper, namer, ObjCExportProblemCollector.SILENT, configuration.objcGenerics))
|
||||
return ObjCExportTranslatorMobile(
|
||||
ObjCExportTranslatorImpl(
|
||||
null,
|
||||
mapper,
|
||||
namer,
|
||||
ObjCExportProblemCollector.SILENT,
|
||||
configuration.objcGenerics
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -17,5 +17,5 @@ class ObjCExportedInterface internal constructor(
|
||||
val topLevel: Map<SourceFile, List<CallableMemberDescriptor>>,
|
||||
val headerLines: List<String>,
|
||||
val namer: ObjCExportNamer,
|
||||
val mapper: ObjCExportMapper
|
||||
val mapper: ObjCExportMapper,
|
||||
)
|
||||
+1
-1
@@ -8,5 +8,5 @@ package org.jetbrains.kotlin.backend.konan.objcexport
|
||||
data class ObjCExportedStubs(
|
||||
val classForwardDeclarations: Set<ObjCClassForwardDeclaration>,
|
||||
val protocolForwardDeclarations: Set<String>,
|
||||
val stubs: List<Stub<*>>
|
||||
val stubs: List<Stub<*>>,
|
||||
)
|
||||
+3
-3
@@ -11,9 +11,9 @@ import org.jetbrains.kotlin.konan.file.File
|
||||
// Later it will accept an object with ObjC declarations instead of lines.
|
||||
class ObjCHeaderWriter {
|
||||
fun write(
|
||||
headerName: String,
|
||||
headerLines: List<String>,
|
||||
headersDirectory: File,
|
||||
headerName: String,
|
||||
headerLines: List<String>,
|
||||
headersDirectory: File,
|
||||
) {
|
||||
headersDirectory.child(headerName).writeLines(headerLines)
|
||||
}
|
||||
|
||||
+14
-13
@@ -7,23 +7,24 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
|
||||
class ObjcExportHeaderGeneratorMobile internal constructor(
|
||||
moduleDescriptors: List<ModuleDescriptor>,
|
||||
mapper: ObjCExportMapper,
|
||||
namer: ObjCExportNamer,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
objcGenerics: Boolean,
|
||||
private val restrictToLocalModules: Boolean
|
||||
moduleDescriptors: List<ModuleDescriptor>,
|
||||
mapper: ObjCExportMapper,
|
||||
namer: ObjCExportNamer,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
objcGenerics: Boolean,
|
||||
private val restrictToLocalModules: Boolean,
|
||||
) : ObjCExportHeaderGenerator(moduleDescriptors, mapper, namer, objcGenerics, problemCollector) {
|
||||
|
||||
companion object {
|
||||
fun createInstance(
|
||||
configuration: ObjCExportLazy.Configuration,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
builtIns: KotlinBuiltIns,
|
||||
moduleDescriptors: List<ModuleDescriptor>,
|
||||
deprecationResolver: DeprecationResolver? = null,
|
||||
local: Boolean = false,
|
||||
restrictToLocalModules: Boolean = false): ObjCExportHeaderGenerator {
|
||||
configuration: ObjCExportLazy.Configuration,
|
||||
problemCollector: ObjCExportProblemCollector,
|
||||
builtIns: KotlinBuiltIns,
|
||||
moduleDescriptors: List<ModuleDescriptor>,
|
||||
deprecationResolver: DeprecationResolver? = null,
|
||||
local: Boolean = false,
|
||||
restrictToLocalModules: Boolean = false,
|
||||
): ObjCExportHeaderGenerator {
|
||||
val mapper = ObjCExportMapper(deprecationResolver, local, configuration.unitSuspendFunctionExport)
|
||||
val namerConfiguration = createNamerConfiguration(configuration)
|
||||
val namer = ObjCExportNamerImpl(namerConfiguration, builtIns, mapper, problemCollector, local)
|
||||
|
||||
+10
-7
@@ -5,11 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.objcexport
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.extractSerializedKdocString
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.findKDocString
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||
import org.jetbrains.kotlin.backend.common.serialization.extractSerializedKdocString
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.findKDocString
|
||||
|
||||
object StubRenderer {
|
||||
fun render(stub: Stub<*>): List<String> = render(stub, false)
|
||||
@@ -39,7 +39,8 @@ object StubRenderer {
|
||||
if (it.startsWith("/**") && it.endsWith("*/")) {
|
||||
// Nested comment is allowed inside of preformatted ``` block in kdoc but not in ObjC
|
||||
val kdocClean = "/**${it.substring(3, it.length - 2).replace("*/", "**").replace("/*", "**")}$kDocEnding"
|
||||
kdocClean.lines().map { it.trim().let {
|
||||
kdocClean.lines().map {
|
||||
it.trim().let {
|
||||
if (it.isNotEmpty() && it[0] == '*') " $it"
|
||||
else it
|
||||
}
|
||||
@@ -51,7 +52,7 @@ object StubRenderer {
|
||||
val kDocAndComment = kDoc?.filterNot { it.isEmpty() }.orEmpty().toMutableList()
|
||||
comment?.contentLines?.let { commentLine ->
|
||||
if (!kDoc.isNullOrEmpty()) kDocAndComment.add(" *") // Separator between nonempty kDoc and nonempty comment
|
||||
commentLine.forEach { kDocAndComment.add(findPositionToInsertGeneratedCommentLine(kDocAndComment, it), " * $it")}
|
||||
commentLine.forEach { kDocAndComment.add(findPositionToInsertGeneratedCommentLine(kDocAndComment, it), " * $it") }
|
||||
}
|
||||
if (kDocAndComment.isNotEmpty()) {
|
||||
+"" // Probably makes the output more readable.
|
||||
@@ -137,8 +138,10 @@ object StubRenderer {
|
||||
}
|
||||
|
||||
fun appendParameters() {
|
||||
assert(method.selectors.size == method.parameters.size ||
|
||||
method.selectors.size == 1 && method.parameters.size == 0)
|
||||
assert(
|
||||
method.selectors.size == method.parameters.size ||
|
||||
method.selectors.size == 1 && method.parameters.size == 0
|
||||
)
|
||||
|
||||
if (method.selectors.size == 1 && method.parameters.size == 0) {
|
||||
append(method.selectors[0])
|
||||
@@ -248,5 +251,5 @@ fun formatGenerics(buffer: Appendable, generics: List<Any>) {
|
||||
|
||||
private fun DeclarationDescriptor.extractKDocString(): String? {
|
||||
return (this as? DeclarationDescriptorWithSource)?.findKDocString()
|
||||
?: extractSerializedKdocString()
|
||||
?: extractSerializedKdocString()
|
||||
}
|
||||
|
||||
+38
-33
@@ -17,11 +17,11 @@ sealed class ObjCType {
|
||||
fun render() = render("")
|
||||
|
||||
protected fun String.withAttrsAndName(attrsAndName: String) =
|
||||
if (attrsAndName.isEmpty()) this else "$this ${attrsAndName.trimStart()}"
|
||||
if (attrsAndName.isEmpty()) this else "$this ${attrsAndName.trimStart()}"
|
||||
}
|
||||
|
||||
data class ObjCRawType(
|
||||
val rawText: String
|
||||
val rawText: String,
|
||||
) : ObjCType() {
|
||||
override fun render(attrsAndName: String): String = rawText.withAttrsAndName(attrsAndName)
|
||||
}
|
||||
@@ -31,8 +31,8 @@ sealed class ObjCReferenceType : ObjCType()
|
||||
sealed class ObjCNonNullReferenceType : ObjCReferenceType()
|
||||
|
||||
data class ObjCNullableReferenceType(
|
||||
val nonNullType: ObjCNonNullReferenceType,
|
||||
val isNullableResult: Boolean = false
|
||||
val nonNullType: ObjCNonNullReferenceType,
|
||||
val isNullableResult: Boolean = false,
|
||||
) : ObjCReferenceType() {
|
||||
override fun render(attrsAndName: String): String {
|
||||
val attribute = if (isNullableResult) objcNullableResultAttribute else objcNullableAttribute
|
||||
@@ -41,8 +41,8 @@ data class ObjCNullableReferenceType(
|
||||
}
|
||||
|
||||
data class ObjCClassType(
|
||||
val className: String,
|
||||
val typeArguments: List<ObjCNonNullReferenceType> = emptyList()
|
||||
val className: String,
|
||||
val typeArguments: List<ObjCNonNullReferenceType> = emptyList(),
|
||||
) : ObjCNonNullReferenceType() {
|
||||
|
||||
override fun render(attrsAndName: String) = buildString {
|
||||
@@ -57,7 +57,7 @@ data class ObjCClassType(
|
||||
}
|
||||
}
|
||||
|
||||
sealed class ObjCGenericTypeUsage: ObjCNonNullReferenceType() {
|
||||
sealed class ObjCGenericTypeUsage : ObjCNonNullReferenceType() {
|
||||
abstract val typeName: String
|
||||
final override fun render(attrsAndName: String): String {
|
||||
return typeName.withAttrsAndName(attrsAndName)
|
||||
@@ -67,15 +67,15 @@ sealed class ObjCGenericTypeUsage: ObjCNonNullReferenceType() {
|
||||
data class ObjCGenericTypeRawUsage(override val typeName: String) : ObjCGenericTypeUsage()
|
||||
|
||||
data class ObjCGenericTypeParameterUsage(
|
||||
val typeParameterDescriptor: TypeParameterDescriptor,
|
||||
val namer: ObjCExportNamer
|
||||
val typeParameterDescriptor: TypeParameterDescriptor,
|
||||
val namer: ObjCExportNamer,
|
||||
) : ObjCGenericTypeUsage() {
|
||||
override val typeName: String
|
||||
get() = namer.getTypeParameterName(typeParameterDescriptor)
|
||||
}
|
||||
|
||||
data class ObjCProtocolType(
|
||||
val protocolName: String
|
||||
val protocolName: String,
|
||||
) : ObjCNonNullReferenceType() {
|
||||
override fun render(attrsAndName: String) = "id<$protocolName>".withAttrsAndName(attrsAndName)
|
||||
}
|
||||
@@ -89,8 +89,8 @@ object ObjCInstanceType : ObjCNonNullReferenceType() {
|
||||
}
|
||||
|
||||
data class ObjCBlockPointerType(
|
||||
val returnType: ObjCType,
|
||||
val parameterTypes: List<ObjCReferenceType>
|
||||
val returnType: ObjCType,
|
||||
val parameterTypes: List<ObjCReferenceType>,
|
||||
) : ObjCNonNullReferenceType() {
|
||||
|
||||
override fun render(attrsAndName: String) = returnType.render(buildString {
|
||||
@@ -108,7 +108,7 @@ object ObjCMetaClassType : ObjCNonNullReferenceType() {
|
||||
}
|
||||
|
||||
sealed class ObjCPrimitiveType(
|
||||
val cName: String
|
||||
val cName: String,
|
||||
) : ObjCType() {
|
||||
object NSUInteger : ObjCPrimitiveType("NSUInteger")
|
||||
object BOOL : ObjCPrimitiveType("BOOL")
|
||||
@@ -125,29 +125,33 @@ sealed class ObjCPrimitiveType(
|
||||
object double : ObjCPrimitiveType("double")
|
||||
object NSInteger : ObjCPrimitiveType("NSInteger")
|
||||
object char : ObjCPrimitiveType("char")
|
||||
object unsigned_char: ObjCPrimitiveType("unsigned char")
|
||||
object unsigned_short: ObjCPrimitiveType("unsigned short")
|
||||
object int: ObjCPrimitiveType("int")
|
||||
object unsigned_int: ObjCPrimitiveType("unsigned int")
|
||||
object long: ObjCPrimitiveType("long")
|
||||
object unsigned_long: ObjCPrimitiveType("unsigned long")
|
||||
object long_long: ObjCPrimitiveType("long long")
|
||||
object unsigned_long_long: ObjCPrimitiveType("unsigned long long")
|
||||
object short: ObjCPrimitiveType("short")
|
||||
object unsigned_char : ObjCPrimitiveType("unsigned char")
|
||||
object unsigned_short : ObjCPrimitiveType("unsigned short")
|
||||
object int : ObjCPrimitiveType("int")
|
||||
object unsigned_int : ObjCPrimitiveType("unsigned int")
|
||||
object long : ObjCPrimitiveType("long")
|
||||
object unsigned_long : ObjCPrimitiveType("unsigned long")
|
||||
object long_long : ObjCPrimitiveType("long long")
|
||||
object unsigned_long_long : ObjCPrimitiveType("unsigned long long")
|
||||
object short : ObjCPrimitiveType("short")
|
||||
|
||||
override fun render(attrsAndName: String) = cName.withAttrsAndName(attrsAndName)
|
||||
}
|
||||
|
||||
data class ObjCPointerType(
|
||||
val pointee: ObjCType,
|
||||
val nullable: Boolean = false
|
||||
val pointee: ObjCType,
|
||||
val nullable: Boolean = false,
|
||||
) : ObjCType() {
|
||||
override fun render(attrsAndName: String) =
|
||||
pointee.render("*${if (nullable) {
|
||||
" $objcNullableAttribute".withAttrsAndName(attrsAndName)
|
||||
} else {
|
||||
attrsAndName
|
||||
}}")
|
||||
pointee.render(
|
||||
"*${
|
||||
if (nullable) {
|
||||
" $objcNullableAttribute".withAttrsAndName(attrsAndName)
|
||||
} else {
|
||||
attrsAndName
|
||||
}
|
||||
}"
|
||||
)
|
||||
}
|
||||
|
||||
object ObjCVoidType : ObjCType() {
|
||||
@@ -158,6 +162,7 @@ object ObjCVoidType : ObjCType() {
|
||||
enum class ObjCValueType(val encoding: String) {
|
||||
BOOL("c"),
|
||||
UNICHAR("S"),
|
||||
|
||||
// TODO: Switch to explicit SIGNED_CHAR
|
||||
CHAR("c"),
|
||||
SHORT("s"),
|
||||
@@ -193,13 +198,13 @@ sealed class ObjCGenericTypeDeclaration {
|
||||
}
|
||||
|
||||
data class ObjCGenericTypeRawDeclaration(
|
||||
override val typeName: String,
|
||||
override val variance: ObjCVariance = ObjCVariance.INVARIANT
|
||||
override val typeName: String,
|
||||
override val variance: ObjCVariance = ObjCVariance.INVARIANT,
|
||||
) : ObjCGenericTypeDeclaration()
|
||||
|
||||
data class ObjCGenericTypeParameterDeclaration(
|
||||
val typeParameterDescriptor: TypeParameterDescriptor,
|
||||
val namer: ObjCExportNamer
|
||||
val typeParameterDescriptor: TypeParameterDescriptor,
|
||||
val namer: ObjCExportNamer,
|
||||
) : ObjCGenericTypeDeclaration() {
|
||||
override val typeName: String
|
||||
get() = namer.getTypeParameterName(typeParameterDescriptor)
|
||||
|
||||
+68
-54
@@ -6,7 +6,10 @@
|
||||
package org.jetbrains.kotlin.backend.konan.objcexport
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||
|
||||
@@ -15,8 +18,8 @@ class ObjCComment(val contentLines: List<String>) {
|
||||
}
|
||||
|
||||
data class ObjCClassForwardDeclaration(
|
||||
val className: String,
|
||||
val typeDeclarations: List<ObjCGenericTypeDeclaration> = emptyList()
|
||||
val className: String,
|
||||
val typeDeclarations: List<ObjCGenericTypeDeclaration> = emptyList(),
|
||||
)
|
||||
|
||||
abstract class Stub<out D : DeclarationDescriptor>(val name: String, val comment: ObjCComment? = null) {
|
||||
@@ -29,78 +32,89 @@ abstract class Stub<out D : DeclarationDescriptor>(val name: String, val comment
|
||||
|
||||
abstract class ObjCTopLevel<out D : DeclarationDescriptor>(name: String, comment: ObjCComment? = null) : Stub<D>(name, comment)
|
||||
|
||||
abstract class ObjCClass<out D : DeclarationDescriptor>(name: String,
|
||||
val attributes: List<String>,
|
||||
comment: ObjCComment? = null) : ObjCTopLevel<D>(name, comment) {
|
||||
abstract class ObjCClass<out D : DeclarationDescriptor>(
|
||||
name: String,
|
||||
val attributes: List<String>,
|
||||
comment: ObjCComment? = null,
|
||||
) : ObjCTopLevel<D>(name, comment) {
|
||||
abstract val superProtocols: List<String>
|
||||
abstract val members: List<Stub<*>>
|
||||
}
|
||||
|
||||
abstract class ObjCProtocol(name: String,
|
||||
attributes: List<String>,
|
||||
comment: ObjCComment? = null) : ObjCClass<ClassDescriptor>(name, attributes, comment)
|
||||
abstract class ObjCProtocol(
|
||||
name: String,
|
||||
attributes: List<String>,
|
||||
comment: ObjCComment? = null,
|
||||
) : ObjCClass<ClassDescriptor>(name, attributes, comment)
|
||||
|
||||
class ObjCProtocolImpl(
|
||||
name: String,
|
||||
override val descriptor: ClassDescriptor,
|
||||
override val superProtocols: List<String>,
|
||||
override val members: List<Stub<*>>,
|
||||
attributes: List<String> = emptyList(),
|
||||
comment: ObjCComment? = null) : ObjCProtocol(name, attributes, comment)
|
||||
name: String,
|
||||
override val descriptor: ClassDescriptor,
|
||||
override val superProtocols: List<String>,
|
||||
override val members: List<Stub<*>>,
|
||||
attributes: List<String> = emptyList(),
|
||||
comment: ObjCComment? = null,
|
||||
) : ObjCProtocol(name, attributes, comment)
|
||||
|
||||
abstract class ObjCInterface(name: String,
|
||||
val generics: List<ObjCGenericTypeDeclaration>,
|
||||
val categoryName: String?,
|
||||
attributes: List<String>,
|
||||
comment: ObjCComment? = null) : ObjCClass<ClassDescriptor>(name, attributes, comment) {
|
||||
abstract class ObjCInterface(
|
||||
name: String,
|
||||
val generics: List<ObjCGenericTypeDeclaration>,
|
||||
val categoryName: String?,
|
||||
attributes: List<String>,
|
||||
comment: ObjCComment? = null,
|
||||
) : ObjCClass<ClassDescriptor>(name, attributes, comment) {
|
||||
abstract val superClass: String?
|
||||
abstract val superClassGenerics: List<ObjCNonNullReferenceType>
|
||||
}
|
||||
|
||||
class ObjCInterfaceImpl(
|
||||
name: String,
|
||||
generics: List<ObjCGenericTypeDeclaration> = emptyList(),
|
||||
override val descriptor: ClassDescriptor? = null,
|
||||
override val superClass: String? = null,
|
||||
override val superClassGenerics: List<ObjCNonNullReferenceType> = emptyList(),
|
||||
override val superProtocols: List<String> = emptyList(),
|
||||
categoryName: String? = null,
|
||||
override val members: List<Stub<*>> = emptyList(),
|
||||
attributes: List<String> = emptyList(),
|
||||
comment: ObjCComment? = null
|
||||
name: String,
|
||||
generics: List<ObjCGenericTypeDeclaration> = emptyList(),
|
||||
override val descriptor: ClassDescriptor? = null,
|
||||
override val superClass: String? = null,
|
||||
override val superClassGenerics: List<ObjCNonNullReferenceType> = emptyList(),
|
||||
override val superProtocols: List<String> = emptyList(),
|
||||
categoryName: String? = null,
|
||||
override val members: List<Stub<*>> = emptyList(),
|
||||
attributes: List<String> = emptyList(),
|
||||
comment: ObjCComment? = null,
|
||||
) : ObjCInterface(name, generics, categoryName, attributes, comment)
|
||||
|
||||
class ObjCMethod(
|
||||
override val descriptor: DeclarationDescriptor?,
|
||||
val isInstanceMethod: Boolean,
|
||||
val returnType: ObjCType,
|
||||
val selectors: List<String>,
|
||||
val parameters: List<ObjCParameter>,
|
||||
val attributes: List<String>,
|
||||
comment: ObjCComment? = null
|
||||
override val descriptor: DeclarationDescriptor?,
|
||||
val isInstanceMethod: Boolean,
|
||||
val returnType: ObjCType,
|
||||
val selectors: List<String>,
|
||||
val parameters: List<ObjCParameter>,
|
||||
val attributes: List<String>,
|
||||
comment: ObjCComment? = null,
|
||||
) : Stub<DeclarationDescriptor>(buildMethodName(selectors, parameters), comment)
|
||||
|
||||
class ObjCParameter(name: String,
|
||||
override val descriptor: ParameterDescriptor?,
|
||||
val type: ObjCType) : Stub<ParameterDescriptor>(name)
|
||||
class ObjCParameter(
|
||||
name: String,
|
||||
override val descriptor: ParameterDescriptor?,
|
||||
val type: ObjCType,
|
||||
) : Stub<ParameterDescriptor>(name)
|
||||
|
||||
class ObjCProperty(name: String,
|
||||
override val descriptor: DeclarationDescriptorWithSource?,
|
||||
val type: ObjCType,
|
||||
val propertyAttributes: List<String>,
|
||||
val setterName: String? = null,
|
||||
val getterName: String? = null,
|
||||
val declarationAttributes: List<String> = emptyList(),
|
||||
comment: ObjCComment? = null) : Stub<DeclarationDescriptorWithSource>(name, comment) {
|
||||
class ObjCProperty(
|
||||
name: String,
|
||||
override val descriptor: DeclarationDescriptorWithSource?,
|
||||
val type: ObjCType,
|
||||
val propertyAttributes: List<String>,
|
||||
val setterName: String? = null,
|
||||
val getterName: String? = null,
|
||||
val declarationAttributes: List<String> = emptyList(),
|
||||
comment: ObjCComment? = null,
|
||||
) : Stub<DeclarationDescriptorWithSource>(name, comment) {
|
||||
|
||||
@Deprecated("", ReplaceWith("this.propertyAttributes"), DeprecationLevel.WARNING)
|
||||
val attributes: List<String> get() = propertyAttributes
|
||||
}
|
||||
|
||||
private fun buildMethodName(selectors: List<String>, parameters: List<ObjCParameter>): String =
|
||||
if (selectors.size == 1 && parameters.size == 0) {
|
||||
selectors[0]
|
||||
} else {
|
||||
assert(selectors.size == parameters.size)
|
||||
selectors.joinToString(separator = "")
|
||||
}
|
||||
if (selectors.size == 1 && parameters.size == 0) {
|
||||
selectors[0]
|
||||
} else {
|
||||
assert(selectors.size == parameters.size)
|
||||
selectors.joinToString(separator = "")
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import java.io.File
|
||||
import kotlin.test.fail
|
||||
|
||||
abstract class AbstractObjCExportHeaderGeneratorTest(
|
||||
private val generator: ObjCExportHeaderGenerator
|
||||
private val generator: ObjCExportHeaderGenerator,
|
||||
) {
|
||||
|
||||
fun interface ObjCExportHeaderGenerator {
|
||||
|
||||
+2
-2
@@ -39,7 +39,7 @@ import java.io.File
|
||||
fun createModuleDescriptor(
|
||||
environment: KotlinCoreEnvironment,
|
||||
tempDir: File,
|
||||
kotlinSources: List<String>
|
||||
kotlinSources: List<String>,
|
||||
): ModuleDescriptor {
|
||||
val testModuleRoot = tempDir.resolve("testModule")
|
||||
testModuleRoot.mkdirs()
|
||||
@@ -74,7 +74,7 @@ fun createModuleDescriptor(
|
||||
}
|
||||
|
||||
fun createKotlinCoreEnvironment(
|
||||
disposable: Disposable, compilerConfiguration: CompilerConfiguration = createCompilerConfiguration()
|
||||
disposable: Disposable, compilerConfiguration: CompilerConfiguration = createCompilerConfiguration(),
|
||||
): KotlinCoreEnvironment {
|
||||
return KotlinCoreEnvironment.createForTests(
|
||||
parentDisposable = disposable,
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
|
||||
internal fun createObjCExportNamerConfiguration(
|
||||
topLevelNamePrefix: String = "",
|
||||
additionalPrefix: (moduleName: Name) -> String? = { null }
|
||||
additionalPrefix: (moduleName: Name) -> String? = { null },
|
||||
): ObjCExportNamer.Configuration {
|
||||
return object : ObjCExportNamer.Configuration {
|
||||
override val topLevelNamePrefix: String get() = topLevelNamePrefix
|
||||
@@ -30,7 +30,7 @@ internal fun createObjCExportNamerConfiguration(
|
||||
internal fun createObjCExportMapper(
|
||||
deprecationResolver: DeprecationResolver? = null,
|
||||
local: Boolean = false,
|
||||
unitSuspendFunctionObjCExport: UnitSuspendFunctionObjCExport = UnitSuspendFunctionObjCExport.DEFAULT
|
||||
unitSuspendFunctionObjCExport: UnitSuspendFunctionObjCExport = UnitSuspendFunctionObjCExport.DEFAULT,
|
||||
): ObjCExportMapper {
|
||||
return ObjCExportMapper(deprecationResolver, local, unitSuspendFunctionObjCExport)
|
||||
}
|
||||
|
||||
+5
-3
@@ -84,9 +84,11 @@ class ObjCExportMapperTest : InlineSourceTestEnvironment {
|
||||
val intClassDescriptor = module.findClassAcrossModuleDependencies(ClassId.fromString("kotlin/Int"))!!
|
||||
|
||||
/* Represents List<Int> */
|
||||
val listOfIntType = KotlinTypeFactory.simpleNotNullType(TypeAttributes.Empty, listClassDescriptor, listOf(
|
||||
TypeProjectionImpl(KotlinTypeFactory.simpleNotNullType(TypeAttributes.Empty, intClassDescriptor, emptyList()))
|
||||
))
|
||||
val listOfIntType = KotlinTypeFactory.simpleNotNullType(
|
||||
TypeAttributes.Empty, listClassDescriptor, listOf(
|
||||
TypeProjectionImpl(KotlinTypeFactory.simpleNotNullType(TypeAttributes.Empty, intClassDescriptor, emptyList()))
|
||||
)
|
||||
)
|
||||
|
||||
val typeMapper = assertNotNull(objcExportMapper.getCustomTypeMapper(listClassDescriptor))
|
||||
assertEquals(ClassId.fromString("kotlin/collections/List"), typeMapper.mappedClassId)
|
||||
|
||||
+24
-12
@@ -96,12 +96,14 @@ class ObjCExportNamerTest : InlineSourceTestEnvironment {
|
||||
val foo = module.getPackage(FqName.ROOT).memberScope.findFirstVariable("foo") { true }!!
|
||||
assertEquals(
|
||||
PropertyName("foo", "foo"),
|
||||
createObjCExportNamer(createObjCExportNamerConfiguration(topLevelNamePrefix = "X")).getPropertyName(foo))
|
||||
createObjCExportNamer(createObjCExportNamerConfiguration(topLevelNamePrefix = "X")).getPropertyName(foo)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test - function inside class`() {
|
||||
val module = createModuleDescriptor("""
|
||||
val module = createModuleDescriptor(
|
||||
"""
|
||||
package bar
|
||||
class Foo {
|
||||
fun someFunction(a: Int, b: Int) = a + b
|
||||
@@ -117,10 +119,12 @@ class ObjCExportNamerTest : InlineSourceTestEnvironment {
|
||||
|
||||
@Test
|
||||
fun `test - class with ObjCName annotation`() {
|
||||
val module = createModuleDescriptor("""
|
||||
val module = createModuleDescriptor(
|
||||
"""
|
||||
@kotlin.native.ObjCName("ObjCFoo", "SwiftFoo")
|
||||
class Foo
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val fooClass = module.findClassAcrossModuleDependencies(ClassId.fromString("Foo"))!!
|
||||
assertEquals(
|
||||
@@ -139,10 +143,12 @@ class ObjCExportNamerTest : InlineSourceTestEnvironment {
|
||||
|
||||
@Test
|
||||
fun `test - parameter with ObjCName annotation`() {
|
||||
val module = createModuleDescriptor("""
|
||||
val module = createModuleDescriptor(
|
||||
"""
|
||||
import kotlin.native.ObjCName
|
||||
fun foo(@ObjCName("aObjC", "aSwift") a: Int)
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val foo = module.getPackage(FqName.ROOT).memberScope.findSingleFunction(Name.identifier("foo"))
|
||||
val parameterA = foo.valueParameters.find { it.name == Name.identifier("a") }!!
|
||||
@@ -152,14 +158,18 @@ class ObjCExportNamerTest : InlineSourceTestEnvironment {
|
||||
@Test
|
||||
fun `test - class mangling`() {
|
||||
val module = createModuleDescriptor {
|
||||
source("""
|
||||
source(
|
||||
"""
|
||||
package a
|
||||
class Foo
|
||||
""".trimIndent())
|
||||
source("""
|
||||
""".trimIndent()
|
||||
)
|
||||
source(
|
||||
"""
|
||||
package b
|
||||
class Foo
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
val aFoo = module.findClassAcrossModuleDependencies(ClassId.fromString("a/Foo"))!!
|
||||
@@ -175,11 +185,13 @@ class ObjCExportNamerTest : InlineSourceTestEnvironment {
|
||||
|
||||
@Test
|
||||
fun `test - simple enum`() {
|
||||
val module = createModuleDescriptor("""
|
||||
val module = createModuleDescriptor(
|
||||
"""
|
||||
enum class Foo {
|
||||
A, B, C
|
||||
}
|
||||
""".trimIndent())
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val foo = module.findClassAcrossModuleDependencies(ClassId.fromString("Foo"))!!
|
||||
val fooA = foo.enumEntries.find { it.name == Name.identifier("A") }!!
|
||||
|
||||
Reference in New Issue
Block a user