Implement '-Xexport-library=<path>' compiler argument (#2262)
Produced framework includes the entire API of exported libraries
This commit is contained in:
committed by
GitHub
parent
4f0633412d
commit
d02a51ba98
@@ -188,6 +188,8 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
|||||||
if (arguments.friendModules != null)
|
if (arguments.friendModules != null)
|
||||||
put(FRIEND_MODULES, arguments.friendModules!!.split(File.pathSeparator).filterNot(String::isEmpty))
|
put(FRIEND_MODULES, arguments.friendModules!!.split(File.pathSeparator).filterNot(String::isEmpty))
|
||||||
|
|
||||||
|
put(EXPORTED_LIBRARIES, selectExportedLibraries(configuration, arguments, outputKind))
|
||||||
|
|
||||||
put(BITCODE_EMBEDDING_MODE, selectBitcodeEmbeddingMode(this, arguments, outputKind))
|
put(BITCODE_EMBEDDING_MODE, selectBitcodeEmbeddingMode(this, arguments, outputKind))
|
||||||
put(DEBUG_INFO_VERSION, arguments.debugInfoFormatVersion.toInt())
|
put(DEBUG_INFO_VERSION, arguments.debugInfoFormatVersion.toInt())
|
||||||
}
|
}
|
||||||
@@ -254,5 +256,22 @@ private fun selectBitcodeEmbeddingMode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun selectExportedLibraries(
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
arguments: K2NativeCompilerArguments,
|
||||||
|
outputKind: CompilerOutputKind
|
||||||
|
): List<String> {
|
||||||
|
val exportedLibraries = arguments.exportedLibraries?.toList().orEmpty()
|
||||||
|
|
||||||
|
return if (exportedLibraries.isNotEmpty() && outputKind != CompilerOutputKind.FRAMEWORK) {
|
||||||
|
configuration.report(STRONG_WARNING, "-Xexport-library is only supported when producing frameworks, " +
|
||||||
|
"but the compiler is producing ${outputKind.name.toLowerCase()}")
|
||||||
|
|
||||||
|
emptyList()
|
||||||
|
} else {
|
||||||
|
exportedLibraries
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) = K2Native.main(args)
|
fun main(args: Array<String>) = K2Native.main(args)
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,14 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value = "-Xenable", deprecatedName = "--enable", valueDescription = "<Phase>", description = "Enable backend phase")
|
@Argument(value = "-Xenable", deprecatedName = "--enable", valueDescription = "<Phase>", description = "Enable backend phase")
|
||||||
var enablePhases: Array<String>? = null
|
var enablePhases: Array<String>? = null
|
||||||
|
|
||||||
|
@Argument(
|
||||||
|
value = "-Xexport-library",
|
||||||
|
valueDescription = "<path>",
|
||||||
|
description = "Path to the library to be included into produced framework API\n" +
|
||||||
|
"Must be the path of a library passed with '-library'"
|
||||||
|
)
|
||||||
|
var exportedLibraries: Array<String>? = null
|
||||||
|
|
||||||
@Argument(value= "-Xlist-phases", deprecatedName = "--list_phases", description = "List all backend phases")
|
@Argument(value= "-Xlist-phases", deprecatedName = "--list_phases", description = "List all backend phases")
|
||||||
var listPhases: Boolean = false
|
var listPhases: Boolean = false
|
||||||
|
|
||||||
|
|||||||
+84
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.SyntheticModulesOrigin
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.konanModuleOrigin
|
||||||
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
|
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||||
|
import org.jetbrains.kotlin.konan.library.isInterop
|
||||||
|
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolveResult
|
||||||
|
|
||||||
|
internal fun validateExportedLibraries(configuration: CompilerConfiguration, resolvedLibraries: KonanLibraryResolveResult) {
|
||||||
|
getExportedLibraries(configuration, resolvedLibraries, report = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun Context.getExportedDependencies(): List<ModuleDescriptor> {
|
||||||
|
val exportedLibraries = getExportedLibraries(this.config.configuration, this.config.resolvedLibraries, report = false)
|
||||||
|
.toSet()
|
||||||
|
|
||||||
|
val result = this.moduleDescriptor.allDependencyModules.filter {
|
||||||
|
val origin = it.konanModuleOrigin
|
||||||
|
when (origin) {
|
||||||
|
CurrentKonanModuleOrigin, SyntheticModulesOrigin -> false
|
||||||
|
is DeserializedKonanModuleOrigin -> {
|
||||||
|
origin.library in exportedLibraries
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getExportedLibraries(
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
resolvedLibraries: KonanLibraryResolveResult,
|
||||||
|
report: Boolean
|
||||||
|
): List<KonanLibrary> {
|
||||||
|
val exportedLibraries = configuration.getList(KonanConfigKeys.EXPORTED_LIBRARIES).map { File(it) }.toSet()
|
||||||
|
val remainingExportedLibraries = exportedLibraries.toMutableSet()
|
||||||
|
|
||||||
|
val result = mutableListOf<KonanLibrary>()
|
||||||
|
|
||||||
|
val libraries = resolvedLibraries.getFullList(null)
|
||||||
|
|
||||||
|
for (library in libraries) {
|
||||||
|
val libraryFile = library.libraryFile
|
||||||
|
if (libraryFile in exportedLibraries) {
|
||||||
|
remainingExportedLibraries -= libraryFile
|
||||||
|
if (library.isInterop || library.isDefault) {
|
||||||
|
if (report) {
|
||||||
|
val kind = if (library.isInterop) "Interop" else "Default"
|
||||||
|
configuration.report(
|
||||||
|
CompilerMessageSeverity.STRONG_WARNING,
|
||||||
|
"$kind library ${library.libraryName} can't be exported with -Xexport-library"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result += library
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (report && remainingExportedLibraries.isNotEmpty()) {
|
||||||
|
val message = buildString {
|
||||||
|
appendln("Following libraries are specified to be exported with -Xexport-library, but not included to the build:")
|
||||||
|
remainingExportedLibraries.forEach { appendln(it) }
|
||||||
|
appendln()
|
||||||
|
appendln("Included libraries:")
|
||||||
|
libraries.forEach { appendln(it.libraryFile) }
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration.report(CompilerMessageSeverity.STRONG_WARNING, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
+4
-1
@@ -94,7 +94,10 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
resolver.resolveWithDependencies(
|
resolver.resolveWithDependencies(
|
||||||
unresolvedLibraries,
|
unresolvedLibraries,
|
||||||
noStdLib = configuration.getBoolean(KonanConfigKeys.NOSTDLIB),
|
noStdLib = configuration.getBoolean(KonanConfigKeys.NOSTDLIB),
|
||||||
noDefaultLibs = configuration.getBoolean(KonanConfigKeys.NODEFAULTLIBS) )
|
noDefaultLibs = configuration.getBoolean(KonanConfigKeys.NODEFAULTLIBS)).also {
|
||||||
|
|
||||||
|
validateExportedLibraries(configuration, it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun librariesWithDependencies(moduleDescriptor: ModuleDescriptor?): List<KonanLibrary> {
|
fun librariesWithDependencies(moduleDescriptor: ModuleDescriptor?): List<KonanLibrary> {
|
||||||
|
|||||||
+2
@@ -28,6 +28,8 @@ class KonanConfigKeys {
|
|||||||
= CompilerConfigurationKey.create("enable backend phases")
|
= CompilerConfigurationKey.create("enable backend phases")
|
||||||
val ENTRY: CompilerConfigurationKey<String?>
|
val ENTRY: CompilerConfigurationKey<String?>
|
||||||
= CompilerConfigurationKey.create("fully qualified main() name")
|
= CompilerConfigurationKey.create("fully qualified main() name")
|
||||||
|
val EXPORTED_LIBRARIES: CompilerConfigurationKey<List<String>>
|
||||||
|
= CompilerConfigurationKey.create<List<String>>("libraries included into produced framework API")
|
||||||
val FRIEND_MODULES: CompilerConfigurationKey<List<String>>
|
val FRIEND_MODULES: CompilerConfigurationKey<List<String>>
|
||||||
= CompilerConfigurationKey.create<List<String>>("friend module paths")
|
= CompilerConfigurationKey.create<List<String>>("friend module paths")
|
||||||
val GENERATE_TEST_RUNNER: CompilerConfigurationKey<Boolean>
|
val GENERATE_TEST_RUNNER: CompilerConfigurationKey<Boolean>
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@ internal class ObjCExport(val codegen: CodeGenerator) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val namer = ObjCExportNamerImpl(context.moduleDescriptor, context.builtIns, mapper)
|
val namer = ObjCExportNamerImpl(emptySet(), context.builtIns, mapper, context.moduleDescriptor.namePrefix)
|
||||||
objCCodeGenerator = ObjCExportCodeGenerator(codegen, namer, mapper)
|
objCCodeGenerator = ObjCExportCodeGenerator(codegen, namer, mapper)
|
||||||
|
|
||||||
generatedClasses = emptySet()
|
generatedClasses = emptySet()
|
||||||
|
|||||||
+24
-7
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.konan.descriptors.*
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.konan.isKonanStdlib
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -24,10 +25,24 @@ import org.jetbrains.kotlin.types.typeUtil.supertypes
|
|||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
abstract class ObjCExportHeaderGenerator(
|
abstract class ObjCExportHeaderGenerator(
|
||||||
val moduleDescriptor: ModuleDescriptor,
|
val moduleDescriptors: List<ModuleDescriptor>,
|
||||||
val builtIns: KotlinBuiltIns,
|
val builtIns: KotlinBuiltIns,
|
||||||
topLevelNamePrefix: String = moduleDescriptor.namePrefix
|
topLevelNamePrefix: String
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
builtIns: KotlinBuiltIns,
|
||||||
|
topLevelNamePrefix: String = moduleDescriptor.namePrefix
|
||||||
|
) : this(moduleDescriptor, emptyList(), builtIns, topLevelNamePrefix)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
exportedDependencies: List<ModuleDescriptor>,
|
||||||
|
builtIns: KotlinBuiltIns,
|
||||||
|
topLevelNamePrefix: String = moduleDescriptor.namePrefix
|
||||||
|
) : this(listOf(moduleDescriptor) + exportedDependencies, builtIns, topLevelNamePrefix)
|
||||||
|
|
||||||
internal val mapper: ObjCExportMapper = object : ObjCExportMapper() {
|
internal val mapper: ObjCExportMapper = object : ObjCExportMapper() {
|
||||||
override fun getCategoryMembersFor(descriptor: ClassDescriptor) =
|
override fun getCategoryMembersFor(descriptor: ClassDescriptor) =
|
||||||
extensions[descriptor].orEmpty()
|
extensions[descriptor].orEmpty()
|
||||||
@@ -39,16 +54,18 @@ abstract class ObjCExportHeaderGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val namer = ObjCExportNamerImpl(moduleDescriptor, builtIns, mapper, topLevelNamePrefix)
|
internal val namer = ObjCExportNamerImpl(moduleDescriptors.toSet(), builtIns, mapper, topLevelNamePrefix)
|
||||||
|
|
||||||
internal val generatedClasses = mutableSetOf<ClassDescriptor>()
|
internal val generatedClasses = mutableSetOf<ClassDescriptor>()
|
||||||
internal val topLevel = mutableMapOf<SourceFile, MutableList<CallableMemberDescriptor>>()
|
internal val topLevel = mutableMapOf<SourceFile, MutableList<CallableMemberDescriptor>>()
|
||||||
|
|
||||||
|
private val stdlibModule = moduleDescriptors.first().allDependencyModules.single { it.isKonanStdlib() }
|
||||||
|
|
||||||
private val mappedToNSNumber: List<ClassDescriptor> = with(builtIns) {
|
private val mappedToNSNumber: List<ClassDescriptor> = with(builtIns) {
|
||||||
val result = mutableListOf(boolean, byte, short, int, long, float, double)
|
val result = mutableListOf(boolean, byte, short, int, long, float, double)
|
||||||
|
|
||||||
UnsignedType.values().mapTo(result) { unsignedType ->
|
UnsignedType.values().mapTo(result) { unsignedType ->
|
||||||
moduleDescriptor.findClassAcrossModuleDependencies(unsignedType.classId)!!
|
stdlibModule.findClassAcrossModuleDependencies(unsignedType.classId)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
@@ -69,7 +86,7 @@ abstract class ObjCExportHeaderGenerator(
|
|||||||
NSNumberKind.values().forEach {
|
NSNumberKind.values().forEach {
|
||||||
// TODO: NSNumber seem to have different equality semantics.
|
// TODO: NSNumber seem to have different equality semantics.
|
||||||
if (it.mappedKotlinClassId != null) {
|
if (it.mappedKotlinClassId != null) {
|
||||||
val descriptor = moduleDescriptor.findClassAcrossModuleDependencies(it.mappedKotlinClassId)!!
|
val descriptor = stdlibModule.findClassAcrossModuleDependencies(it.mappedKotlinClassId)!!
|
||||||
result += CustomTypeMapper.Simple(descriptor, namer.numberBoxName(descriptor).objCName)
|
result += CustomTypeMapper.Simple(descriptor, namer.numberBoxName(descriptor).objCName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +198,7 @@ abstract class ObjCExportHeaderGenerator(
|
|||||||
|
|
||||||
genKotlinNumbers()
|
genKotlinNumbers()
|
||||||
|
|
||||||
val packageFragments = moduleDescriptor.getPackageFragments()
|
val packageFragments = moduleDescriptors.flatMap { it.getPackageFragments() }
|
||||||
|
|
||||||
packageFragments.forEach { packageFragment ->
|
packageFragments.forEach { packageFragment ->
|
||||||
packageFragment.getMemberScope().getContributedDescriptors()
|
packageFragment.getMemberScope().getContributedDescriptors()
|
||||||
@@ -263,7 +280,7 @@ abstract class ObjCExportHeaderGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun genKotlinNumber(kotlinClassId: ClassId, kind: NSNumberKind): ObjCInterface {
|
private fun genKotlinNumber(kotlinClassId: ClassId, kind: NSNumberKind): ObjCInterface {
|
||||||
val descriptor = moduleDescriptor.findClassAcrossModuleDependencies(kotlinClassId)!!
|
val descriptor = stdlibModule.findClassAcrossModuleDependencies(kotlinClassId)!!
|
||||||
val name = namer.numberBoxName(descriptor)
|
val name = namer.numberBoxName(descriptor)
|
||||||
|
|
||||||
val members = buildMembers {
|
val members = buildMembers {
|
||||||
|
|||||||
+6
-2
@@ -6,12 +6,16 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.objcexport
|
package org.jetbrains.kotlin.backend.konan.objcexport
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
|
import org.jetbrains.kotlin.backend.konan.getExportedDependencies
|
||||||
import org.jetbrains.kotlin.backend.konan.reportCompilationWarning
|
import org.jetbrains.kotlin.backend.konan.reportCompilationWarning
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.ir.util.report
|
import org.jetbrains.kotlin.ir.util.report
|
||||||
|
|
||||||
internal class ObjCExportHeaderGeneratorImpl(val context: Context)
|
internal class ObjCExportHeaderGeneratorImpl(val context: Context) : ObjCExportHeaderGenerator(
|
||||||
: ObjCExportHeaderGenerator(context.moduleDescriptor, context.builtIns) {
|
context.moduleDescriptor,
|
||||||
|
context.getExportedDependencies(),
|
||||||
|
context.builtIns
|
||||||
|
) {
|
||||||
|
|
||||||
override fun reportWarning(text: String) {
|
override fun reportWarning(text: String) {
|
||||||
context.reportCompilationWarning(text)
|
context.reportCompilationWarning(text)
|
||||||
|
|||||||
+23
-8
@@ -31,8 +31,18 @@ interface ObjCExportNamer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createNamer(moduleDescriptor: ModuleDescriptor,
|
fun createNamer(moduleDescriptor: ModuleDescriptor,
|
||||||
|
topLevelNamePrefix: String = moduleDescriptor.namePrefix): ObjCExportNamer =
|
||||||
|
createNamer(moduleDescriptor, emptyList(), topLevelNamePrefix)
|
||||||
|
|
||||||
|
fun createNamer(moduleDescriptor: ModuleDescriptor,
|
||||||
|
exportedDependencies: List<ModuleDescriptor>,
|
||||||
topLevelNamePrefix: String = moduleDescriptor.namePrefix): ObjCExportNamer {
|
topLevelNamePrefix: String = moduleDescriptor.namePrefix): ObjCExportNamer {
|
||||||
val generator = object : ObjCExportHeaderGenerator(moduleDescriptor, moduleDescriptor.builtIns, topLevelNamePrefix) {
|
val generator = object : ObjCExportHeaderGenerator(
|
||||||
|
moduleDescriptor,
|
||||||
|
exportedDependencies,
|
||||||
|
moduleDescriptor.builtIns,
|
||||||
|
topLevelNamePrefix
|
||||||
|
) {
|
||||||
override fun reportWarning(text: String) {}
|
override fun reportWarning(text: String) {}
|
||||||
override fun reportWarning(method: FunctionDescriptor, text: String) {}
|
override fun reportWarning(method: FunctionDescriptor, text: String) {}
|
||||||
}
|
}
|
||||||
@@ -40,10 +50,10 @@ fun createNamer(moduleDescriptor: ModuleDescriptor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class ObjCExportNamerImpl(
|
internal class ObjCExportNamerImpl(
|
||||||
val moduleDescriptor: ModuleDescriptor,
|
val moduleDescriptors: Set<ModuleDescriptor>,
|
||||||
builtIns: KotlinBuiltIns,
|
builtIns: KotlinBuiltIns,
|
||||||
val mapper: ObjCExportMapper,
|
val mapper: ObjCExportMapper,
|
||||||
private val topLevelNamePrefix: String = moduleDescriptor.namePrefix
|
private val topLevelNamePrefix: String
|
||||||
) : ObjCExportNamer {
|
) : ObjCExportNamer {
|
||||||
|
|
||||||
private fun String.toUnmangledClassOrProtocolName(): ObjCExportNamer.ClassOrProtocolName =
|
private fun String.toUnmangledClassOrProtocolName(): ObjCExportNamer.ClassOrProtocolName =
|
||||||
@@ -128,10 +138,15 @@ internal class ObjCExportNamerImpl(
|
|||||||
|
|
||||||
override fun getFileClassName(file: SourceFile): ObjCExportNamer.ClassOrProtocolName {
|
override fun getFileClassName(file: SourceFile): ObjCExportNamer.ClassOrProtocolName {
|
||||||
val baseName by lazy {
|
val baseName by lazy {
|
||||||
val psiSourceFile = file as? PsiSourceFile ?: error("SourceFile '$file' is not PsiSourceFile")
|
val fileName = when (file) {
|
||||||
val psiFile = psiSourceFile.psiFile
|
is PsiSourceFile -> {
|
||||||
val ktFile = psiFile as? KtFile ?: error("PsiFile '$psiFile' is not KtFile")
|
val psiFile = file.psiFile
|
||||||
PackagePartClassUtils.getFilePartShortName(ktFile.name)
|
val ktFile = psiFile as? KtFile ?: error("PsiFile '$psiFile' is not KtFile")
|
||||||
|
ktFile.name
|
||||||
|
}
|
||||||
|
else -> file.name ?: error("$file has no name")
|
||||||
|
}
|
||||||
|
PackagePartClassUtils.getFilePartShortName(fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
val objCName = objCClassNames.getOrPut(file) {
|
val objCName = objCClassNames.getOrPut(file) {
|
||||||
@@ -196,7 +211,7 @@ internal class ObjCExportNamerImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun StringBuilder.appendTopLevelClassBaseName(descriptor: ClassDescriptor) = apply {
|
private fun StringBuilder.appendTopLevelClassBaseName(descriptor: ClassDescriptor) = apply {
|
||||||
if (descriptor.module != moduleDescriptor) {
|
if (descriptor.module !in moduleDescriptors) {
|
||||||
append(descriptor.module.namePrefix)
|
append(descriptor.module.namePrefix)
|
||||||
}
|
}
|
||||||
append(descriptor.name.asString())
|
append(descriptor.name.asString())
|
||||||
|
|||||||
Reference in New Issue
Block a user