[K/N] Warn if the inferred main package of a framework is root

This commit is contained in:
Ilya Matveev
2021-09-20 20:27:48 +07:00
committed by Space
parent bfe336b0db
commit f93d5604aa
2 changed files with 35 additions and 20 deletions
@@ -14,8 +14,10 @@ import org.jetbrains.kotlin.backend.konan.getExportedDependencies
import org.jetbrains.kotlin.backend.konan.llvm.CodeGenerator
import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportBlockCodeGenerator
import org.jetbrains.kotlin.backend.konan.llvm.objcexport.ObjCExportCodeGenerator
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.konan.exec.Command
@@ -158,10 +160,7 @@ internal class ObjCExport(val context: Context, symbolTable: SymbolTable) {
}
val file = directory.child("Info.plist")
// TODO: consider showing warning if the main package is root.
val bundleId = context.configuration[BUNDLE_ID]
?: guessMainPackage().child(Name.identifier(name)).asString()
val bundleId = guessBundleID(name)
val platform = properties.platformName()
val minimumOsVersion = properties.osVersionMin
@@ -293,8 +292,12 @@ internal class ObjCExport(val context: Context, symbolTable: SymbolTable) {
}
}
private fun guessMainPackage(): FqName {
val allPackages = (context.getIncludedLibraryDescriptors() + context.getExportedDependencies() + context.moduleDescriptor).flatMap {
private fun guessMainPackage(modules: List<ModuleDescriptor>): FqName? {
if (modules.isEmpty()) {
return null
}
val allPackages = modules.flatMap {
it.getPackageFragments() // Includes also all parent packages, e.g. the root one.
}
@@ -305,6 +308,30 @@ internal class ObjCExport(val context: Context, symbolTable: SymbolTable) {
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 }!!
.maxByOrNull { it.asString().length }
}
private fun guessBundleID(bundleName: String): String {
val configuration = context.configuration
configuration[BUNDLE_ID]?.let {
return it
}
// Consider exported libraries only if we cannot infer the package from sources or included libs.
val mainPackage = guessMainPackage(context.getIncludedLibraryDescriptors() + context.moduleDescriptor)
?: guessMainPackage(context.getExportedDependencies())
?: FqName.ROOT
val bundleID = mainPackage.child(Name.identifier(bundleName)).asString()
if (mainPackage.isRoot) {
configuration.report(
CompilerMessageSeverity.STRONG_WARNING,
"Cannot infer a bundle ID from packages of source files and exported dependencies, " +
"use the bundle name instead: $bundleName. " +
"Please specify the bundle ID explicitly using the -Xbundle-id compiler flag."
)
}
return bundleID
}
}
@@ -5486,20 +5486,8 @@ if (isAppleTarget(project)) {
def currentTarget = project.target.name
enabled = currentTarget.startsWith("mac")
konanArtifacts {
library("frameworkBundleIdLib", targets: [target.name]) {
srcFiles("framework/bundle_id/lib.kt")
delegate.getByTarget(target.name).configure{
UtilsKt.dependsOnDist(it)
}
}
}
framework("Foo") {
sources = ["framework/bundle_id/main.kt"]
library = "frameworkBundleIdLib"
def exportedLib = konanArtifacts[library].getArtifactByTarget(target.name)
opts = ["-Xexport-library=$exportedLib"]
sources = ["framework/bundle_id/main.kt", "framework/bundle_id/lib.kt"]
}
swiftSources = []