Improve inner/nested class names in framework
Use 'Outer.Inner' instead of 'OuterInner' for Swift Also do some refactoring and add other minor improvements.
This commit is contained in:
committed by
SvyatoslavScherbina
parent
e4ca831f06
commit
1791ed5643
+72
-31
@@ -46,9 +46,6 @@ internal class ObjCExportNamerImpl(
|
||||
private val topLevelNamePrefix: String = moduleDescriptor.namePrefix
|
||||
) : ObjCExportNamer {
|
||||
|
||||
private fun String.mangleClassOrProtocolName(): ObjCExportNamer.ClassOrProtocolName =
|
||||
ObjCExportNamer.ClassOrProtocolName(swiftName = this, objCName = "$topLevelNamePrefix${this}")
|
||||
|
||||
private fun String.toUnmangledClassOrProtocolName(): ObjCExportNamer.ClassOrProtocolName =
|
||||
ObjCExportNamer.ClassOrProtocolName(swiftName = this, objCName = this)
|
||||
|
||||
@@ -95,13 +92,15 @@ internal class ObjCExportNamerImpl(
|
||||
!mapper.canHaveSameName(first, second)
|
||||
}
|
||||
|
||||
private val classNames = object : Mapping<Any, String>() {
|
||||
override fun conflict(first: Any, second: Any): Boolean = true
|
||||
private inner open class GlobalNameMapping<in T : Any, N> : Mapping<T, N>() {
|
||||
final override fun conflict(first: T, second: T): Boolean = true
|
||||
}
|
||||
|
||||
private val protocolNames = object : Mapping<Any, String>() {
|
||||
override fun conflict(first: Any, second: Any): Boolean = true
|
||||
}
|
||||
private val objCClassNames = GlobalNameMapping<Any, String>()
|
||||
private val objCProtocolNames = GlobalNameMapping<ClassDescriptor, String>()
|
||||
|
||||
// Classes and protocols share the same namespace in Swift.
|
||||
private val swiftClassAndProtocolNames = GlobalNameMapping<Any, String>()
|
||||
|
||||
private abstract inner class ClassPropertyNameMapping<T : Any> : Mapping<T, String>() {
|
||||
|
||||
@@ -127,12 +126,26 @@ internal class ObjCExportNamerImpl(
|
||||
first.containingDeclaration == second.containingDeclaration
|
||||
}
|
||||
|
||||
override fun getFileClassName(file: SourceFile): ObjCExportNamer.ClassOrProtocolName = classNames.getOrPut(file) {
|
||||
val psiSourceFile = file as? PsiSourceFile ?: error("SourceFile '$file' is not PsiSourceFile")
|
||||
val psiFile = psiSourceFile.psiFile
|
||||
val ktFile = psiFile as? KtFile ?: error("PsiFile '$psiFile' is not KtFile")
|
||||
StringBuilder(PackagePartClassUtils.getFilePartShortName(ktFile.name)).mangledSequence { append("_") }
|
||||
}.mangleClassOrProtocolName()
|
||||
override fun getFileClassName(file: SourceFile): ObjCExportNamer.ClassOrProtocolName {
|
||||
val baseName by lazy {
|
||||
val psiSourceFile = file as? PsiSourceFile ?: error("SourceFile '$file' is not PsiSourceFile")
|
||||
val psiFile = psiSourceFile.psiFile
|
||||
val ktFile = psiFile as? KtFile ?: error("PsiFile '$psiFile' is not KtFile")
|
||||
PackagePartClassUtils.getFilePartShortName(ktFile.name)
|
||||
}
|
||||
|
||||
val objCName = objCClassNames.getOrPut(file) {
|
||||
StringBuilder(topLevelNamePrefix).append(baseName)
|
||||
.mangledBySuffixUnderscores()
|
||||
}
|
||||
|
||||
val swiftName = swiftClassAndProtocolNames.getOrPut(file) {
|
||||
StringBuilder(baseName)
|
||||
.mangledBySuffixUnderscores()
|
||||
}
|
||||
|
||||
return ObjCExportNamer.ClassOrProtocolName(swiftName = swiftName, objCName = objCName)
|
||||
}
|
||||
|
||||
private val predefinedClassNames = mapOf(
|
||||
builtIns.any to kotlinAnyName,
|
||||
@@ -140,22 +153,48 @@ internal class ObjCExportNamerImpl(
|
||||
builtIns.mutableMap to mutableMapName
|
||||
)
|
||||
|
||||
override fun getClassOrProtocolName(descriptor: ClassDescriptor): ObjCExportNamer.ClassOrProtocolName {
|
||||
predefinedClassNames[descriptor]?.let { return it }
|
||||
override fun getClassOrProtocolName(descriptor: ClassDescriptor): ObjCExportNamer.ClassOrProtocolName =
|
||||
predefinedClassNames[descriptor]
|
||||
?: ObjCExportNamer.ClassOrProtocolName(
|
||||
swiftName = getClassOrProtocolSwiftName(descriptor),
|
||||
objCName = getClassOrProtocolObjCName(descriptor)
|
||||
)
|
||||
|
||||
val mapping = if (descriptor.isInterface) protocolNames else classNames
|
||||
private fun getClassOrProtocolSwiftName(
|
||||
descriptor: ClassDescriptor
|
||||
): String = swiftClassAndProtocolNames.getOrPut(descriptor) {
|
||||
StringBuilder().apply {
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
if (containingDeclaration is ClassDescriptor) {
|
||||
append(getClassOrProtocolSwiftName(containingDeclaration))
|
||||
.append(".").append(descriptor.name.asString())
|
||||
} else {
|
||||
appendTopLevelClassBaseName(descriptor)
|
||||
}
|
||||
}.mangledBySuffixUnderscores()
|
||||
}
|
||||
|
||||
return mapping.getOrPut(descriptor) {
|
||||
private fun getClassOrProtocolObjCName(descriptor: ClassDescriptor): String {
|
||||
val objCMapping = if (descriptor.isInterface) objCProtocolNames else objCClassNames
|
||||
return objCMapping.getOrPut(descriptor) {
|
||||
StringBuilder().apply {
|
||||
if (descriptor.module != moduleDescriptor) {
|
||||
append(descriptor.module.namePrefix)
|
||||
}
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
if (containingDeclaration is ClassDescriptor) {
|
||||
append(getClassOrProtocolObjCName(containingDeclaration))
|
||||
.append(descriptor.name.asString().capitalize())
|
||||
|
||||
descriptor.parentsWithSelf.takeWhile { it is ClassDescriptor }
|
||||
.toList().reversed()
|
||||
.joinTo(this, "") { it.name.asString().capitalize() }
|
||||
}.mangledSequence { append("_") }
|
||||
}.mangleClassOrProtocolName()
|
||||
} else {
|
||||
append(topLevelNamePrefix).appendTopLevelClassBaseName(descriptor)
|
||||
}
|
||||
}.mangledBySuffixUnderscores()
|
||||
}
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendTopLevelClassBaseName(descriptor: ClassDescriptor) = apply {
|
||||
if (descriptor.module != moduleDescriptor) {
|
||||
append(descriptor.module.namePrefix)
|
||||
}
|
||||
append(descriptor.name.asString())
|
||||
}
|
||||
|
||||
override fun getSelector(method: FunctionDescriptor): String = methodSelectors.getOrPut(method) {
|
||||
@@ -258,7 +297,7 @@ internal class ObjCExportNamerImpl(
|
||||
return objectInstanceSelectors.getOrPut(descriptor) {
|
||||
val name = descriptor.name.asString().decapitalize().mangleIfSpecialFamily("get")
|
||||
|
||||
StringBuilder(name).mangledSequence { append("_") }
|
||||
StringBuilder(name).mangledBySuffixUnderscores()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,7 +311,7 @@ internal class ObjCExportNamerImpl(
|
||||
if (index == 0) lower else lower.capitalize()
|
||||
}.joinToString("").mangleIfSpecialFamily("the")
|
||||
|
||||
StringBuilder(name).mangledSequence { append("_") }
|
||||
StringBuilder(name).mangledBySuffixUnderscores()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,8 +319,8 @@ internal class ObjCExportNamerImpl(
|
||||
val any = builtIns.any
|
||||
|
||||
predefinedClassNames.forEach { descriptor, name ->
|
||||
// Note: it is a hack.
|
||||
classNames.forceAssign(descriptor, name.swiftName)
|
||||
objCClassNames.forceAssign(descriptor, name.objCName)
|
||||
swiftClassAndProtocolNames.forceAssign(descriptor, name.swiftName)
|
||||
}
|
||||
|
||||
fun ClassDescriptor.method(name: String) =
|
||||
@@ -336,7 +375,7 @@ internal class ObjCExportNamerImpl(
|
||||
private fun String.startsWithWords(words: String) = this.startsWith(words) &&
|
||||
(this.length == words.length || !this[words.length].isLowerCase())
|
||||
|
||||
private abstract inner class Mapping<T : Any, N>() {
|
||||
private abstract inner class Mapping<in T : Any, N>() {
|
||||
private val elementToName = mutableMapOf<T, N>()
|
||||
private val nameToElements = mutableMapOf<N, MutableList<T>>()
|
||||
|
||||
@@ -390,6 +429,8 @@ private inline fun StringBuilder.mangledSequence(crossinline mangle: StringBuild
|
||||
this@mangledSequence.toString()
|
||||
}
|
||||
|
||||
private fun StringBuilder.mangledBySuffixUnderscores() = this.mangledSequence { append("_") }
|
||||
|
||||
private fun ObjCExportMapper.canHaveCommonSubtype(first: ClassDescriptor, second: ClassDescriptor): Boolean {
|
||||
if (first.isSubclassOf(second) || second.isSubclassOf(first)) {
|
||||
return true
|
||||
|
||||
@@ -377,7 +377,7 @@ func testDataClass() throws {
|
||||
}
|
||||
|
||||
func testCompanionObj() throws {
|
||||
try assertEquals(actual: WithCompanionAndObjectCompanion().str, expected: "String")
|
||||
try assertEquals(actual: WithCompanionAndObject.Companion().str, expected: "String")
|
||||
try assertEquals(actual: ValuesKt.getCompanionObject().str, expected: "String")
|
||||
|
||||
let namedFromCompanion = ValuesKt.getCompanionObject().named
|
||||
|
||||
Reference in New Issue
Block a user