Add initial support for -Xobjc-generics to ObjCExportLazy
This commit is contained in:
committed by
SvyatoslavScherbina
parent
64ddfee214
commit
d3d3b3aa77
+14
-4
@@ -18,9 +18,7 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.modalityModifier
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierTypeOrDefault
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorResolver
|
import org.jetbrains.kotlin.resolve.DescriptorResolver
|
||||||
@@ -140,12 +138,20 @@ internal class ObjCExportLazyImpl(
|
|||||||
|
|
||||||
LazyObjCInterfaceImpl(name,
|
LazyObjCInterfaceImpl(name,
|
||||||
attributes,
|
attributes,
|
||||||
generics = if (configuration.objcGenerics) TODO() else emptyList(),
|
generics = translateGenerics(ktClassOrObject),
|
||||||
psi = ktClassOrObject,
|
psi = ktClassOrObject,
|
||||||
lazy = this)
|
lazy = this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun translateGenerics(ktClassOrObject: KtClassOrObject): List<String> = if (configuration.objcGenerics) {
|
||||||
|
ktClassOrObject.typeParametersWithOuter
|
||||||
|
.map { nameTranslator.getTypeParameterName(it) }
|
||||||
|
.toList()
|
||||||
|
} else {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
private fun translateTopLevels(file: KtFile): List<ObjCInterface> {
|
private fun translateTopLevels(file: KtFile): List<ObjCInterface> {
|
||||||
val extensions =
|
val extensions =
|
||||||
mutableMapOf<ClassDescriptor, MutableList<KtCallableDeclaration>>()
|
mutableMapOf<ClassDescriptor, MutableList<KtCallableDeclaration>>()
|
||||||
@@ -437,3 +443,7 @@ private val KtCallableDeclaration.isSuspend: Boolean
|
|||||||
|
|
||||||
internal val KtPureClassOrObject.isInterface: Boolean
|
internal val KtPureClassOrObject.isInterface: Boolean
|
||||||
get() = this is KtClass && this.isInterface()
|
get() = this is KtClass && this.isInterface()
|
||||||
|
|
||||||
|
internal val KtClassOrObject.typeParametersWithOuter
|
||||||
|
get() = generateSequence(this, { if (it is KtClass && it.isInner()) it.containingClassOrObject else null })
|
||||||
|
.flatMap { it.typeParameters.asSequence() }
|
||||||
|
|||||||
+18
-12
@@ -29,6 +29,8 @@ internal interface ObjCExportNameTranslator {
|
|||||||
fun getClassOrProtocolName(
|
fun getClassOrProtocolName(
|
||||||
ktClassOrObject: KtClassOrObject
|
ktClassOrObject: KtClassOrObject
|
||||||
): ObjCExportNamer.ClassOrProtocolName
|
): ObjCExportNamer.ClassOrProtocolName
|
||||||
|
|
||||||
|
fun getTypeParameterName(ktTypeParameter: KtTypeParameter): String
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ObjCExportNamer {
|
interface ObjCExportNamer {
|
||||||
@@ -130,6 +132,11 @@ internal open class ObjCExportNameTranslatorImpl(
|
|||||||
append(ownName)
|
append(ownName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getTypeParameterName(ktTypeParameter: KtTypeParameter): String = buildString {
|
||||||
|
append(ktTypeParameter.name!!.toIdentifier())
|
||||||
|
while (helper.isTypeParameterNameReserved(this.toString())) append('_')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ObjCExportNamingHelper(
|
private class ObjCExportNamingHelper(
|
||||||
@@ -161,6 +168,12 @@ private class ObjCExportNamingHelper(
|
|||||||
"Type" -> "${name}_" // See https://github.com/JetBrains/kotlin-native/issues/3167
|
"Type" -> "${name}_" // See https://github.com/JetBrains/kotlin-native/issues/3167
|
||||||
else -> name
|
else -> name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ObjCExportNamerImpl(
|
internal class ObjCExportNamerImpl(
|
||||||
@@ -613,10 +626,6 @@ internal class ObjCExportNamerImpl(
|
|||||||
private val elementToName = mutableMapOf<TypeParameterDescriptor, String>()
|
private val elementToName = mutableMapOf<TypeParameterDescriptor, String>()
|
||||||
private val typeParameterNameClassOverrides = mutableMapOf<ClassDescriptor, MutableSet<String>>()
|
private val typeParameterNameClassOverrides = mutableMapOf<ClassDescriptor, MutableSet<String>>()
|
||||||
|
|
||||||
fun reserved(name: String): Boolean {
|
|
||||||
return name in reservedNames
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getOrPut(element: TypeParameterDescriptor, nameCandidates: () -> Sequence<String>): String {
|
fun getOrPut(element: TypeParameterDescriptor, nameCandidates: () -> Sequence<String>): String {
|
||||||
getIfAssigned(element)?.let { return it }
|
getIfAssigned(element)?.let { return it }
|
||||||
|
|
||||||
@@ -632,7 +641,7 @@ internal class ObjCExportNamerImpl(
|
|||||||
private fun tryAssign(element: TypeParameterDescriptor, name: String): Boolean {
|
private fun tryAssign(element: TypeParameterDescriptor, name: String): Boolean {
|
||||||
if (element in elementToName) error(element)
|
if (element in elementToName) error(element)
|
||||||
|
|
||||||
if (reserved(name)) return false
|
if (helper.isTypeParameterNameReserved(name)) return false
|
||||||
|
|
||||||
if (!validName(element, name)) return false
|
if (!validName(element, name)) return false
|
||||||
|
|
||||||
@@ -644,28 +653,25 @@ internal class ObjCExportNamerImpl(
|
|||||||
private fun assignName(element: TypeParameterDescriptor, name: String) {
|
private fun assignName(element: TypeParameterDescriptor, name: String) {
|
||||||
if (!local) {
|
if (!local) {
|
||||||
elementToName[element] = name
|
elementToName[element] = name
|
||||||
|
classNameSet(element).add(name)
|
||||||
}
|
}
|
||||||
classNameSet(element).add(name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validName(element: TypeParameterDescriptor, name: String): Boolean {
|
private fun validName(element: TypeParameterDescriptor, name: String): Boolean {
|
||||||
assert(element.containingDeclaration is ClassDescriptor)
|
assert(element.containingDeclaration is ClassDescriptor)
|
||||||
|
|
||||||
val nameSet = classNameSet(element)
|
return !objCClassNames.nameExists(name) && !objCProtocolNames.nameExists(name) &&
|
||||||
return !objCClassNames.nameExists(name) && !objCProtocolNames.nameExists(name) && name !in nameSet
|
(local || name !in classNameSet(element))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun classNameSet(element: TypeParameterDescriptor): MutableSet<String> {
|
private fun classNameSet(element: TypeParameterDescriptor): MutableSet<String> {
|
||||||
|
require(!local)
|
||||||
return typeParameterNameClassOverrides.getOrPut(element.containingDeclaration as ClassDescriptor) {
|
return typeParameterNameClassOverrides.getOrPut(element.containingDeclaration as ClassDescriptor) {
|
||||||
mutableSetOf()
|
mutableSetOf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIfAssigned(element: TypeParameterDescriptor): String? = elementToName[element]
|
private fun getIfAssigned(element: TypeParameterDescriptor): String? = elementToName[element]
|
||||||
|
|
||||||
private val reservedNames = 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 abstract inner class Mapping<in T : Any, N>() {
|
private abstract inner class Mapping<in T : Any, N>() {
|
||||||
|
|||||||
Reference in New Issue
Block a user