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.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
||||
import org.jetbrains.kotlin.psi.psiUtil.modalityModifier
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierTypeOrDefault
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorResolver
|
||||
@@ -140,12 +138,20 @@ internal class ObjCExportLazyImpl(
|
||||
|
||||
LazyObjCInterfaceImpl(name,
|
||||
attributes,
|
||||
generics = if (configuration.objcGenerics) TODO() else emptyList(),
|
||||
generics = translateGenerics(ktClassOrObject),
|
||||
psi = ktClassOrObject,
|
||||
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> {
|
||||
val extensions =
|
||||
mutableMapOf<ClassDescriptor, MutableList<KtCallableDeclaration>>()
|
||||
@@ -437,3 +443,7 @@ private val KtCallableDeclaration.isSuspend: Boolean
|
||||
|
||||
internal val KtPureClassOrObject.isInterface: Boolean
|
||||
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(
|
||||
ktClassOrObject: KtClassOrObject
|
||||
): ObjCExportNamer.ClassOrProtocolName
|
||||
|
||||
fun getTypeParameterName(ktTypeParameter: KtTypeParameter): String
|
||||
}
|
||||
|
||||
interface ObjCExportNamer {
|
||||
@@ -130,6 +132,11 @@ internal open class ObjCExportNameTranslatorImpl(
|
||||
append(ownName)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTypeParameterName(ktTypeParameter: KtTypeParameter): String = buildString {
|
||||
append(ktTypeParameter.name!!.toIdentifier())
|
||||
while (helper.isTypeParameterNameReserved(this.toString())) append('_')
|
||||
}
|
||||
}
|
||||
|
||||
private class ObjCExportNamingHelper(
|
||||
@@ -161,6 +168,12 @@ private class ObjCExportNamingHelper(
|
||||
"Type" -> "${name}_" // See https://github.com/JetBrains/kotlin-native/issues/3167
|
||||
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(
|
||||
@@ -613,10 +626,6 @@ internal class ObjCExportNamerImpl(
|
||||
private val elementToName = mutableMapOf<TypeParameterDescriptor, 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 {
|
||||
getIfAssigned(element)?.let { return it }
|
||||
|
||||
@@ -632,7 +641,7 @@ internal class ObjCExportNamerImpl(
|
||||
private fun tryAssign(element: TypeParameterDescriptor, name: String): Boolean {
|
||||
if (element in elementToName) error(element)
|
||||
|
||||
if (reserved(name)) return false
|
||||
if (helper.isTypeParameterNameReserved(name)) return false
|
||||
|
||||
if (!validName(element, name)) return false
|
||||
|
||||
@@ -644,28 +653,25 @@ internal class ObjCExportNamerImpl(
|
||||
private fun assignName(element: TypeParameterDescriptor, name: String) {
|
||||
if (!local) {
|
||||
elementToName[element] = name
|
||||
classNameSet(element).add(name)
|
||||
}
|
||||
classNameSet(element).add(name)
|
||||
}
|
||||
|
||||
private fun validName(element: TypeParameterDescriptor, name: String): Boolean {
|
||||
assert(element.containingDeclaration is ClassDescriptor)
|
||||
|
||||
val nameSet = classNameSet(element)
|
||||
return !objCClassNames.nameExists(name) && !objCProtocolNames.nameExists(name) && name !in nameSet
|
||||
return !objCClassNames.nameExists(name) && !objCProtocolNames.nameExists(name) &&
|
||||
(local || name !in classNameSet(element))
|
||||
}
|
||||
|
||||
private fun classNameSet(element: TypeParameterDescriptor): MutableSet<String> {
|
||||
require(!local)
|
||||
return typeParameterNameClassOverrides.getOrPut(element.containingDeclaration as ClassDescriptor) {
|
||||
mutableSetOf()
|
||||
}
|
||||
}
|
||||
|
||||
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>() {
|
||||
|
||||
Reference in New Issue
Block a user