Properly check platform of klib by reading manifest
This commit is contained in:
committed by
Dmitriy Dolovov
parent
4742057b51
commit
6ccb8cd0a3
@@ -123,5 +123,9 @@ fun buildKoltinLibrary(
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class BuiltInsPlatform {
|
enum class BuiltInsPlatform {
|
||||||
JVM, JS, NATIVE, COMMON
|
JVM, JS, NATIVE, COMMON;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun parseFromString(name: String): BuiltInsPlatform? = values().firstOrNull { it.name == name }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+11
-5
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
|
|||||||
import org.jetbrains.kotlin.idea.klib.getCompatibilityInfo
|
import org.jetbrains.kotlin.idea.klib.getCompatibilityInfo
|
||||||
import org.jetbrains.kotlin.idea.util.IJLoggerAdapter
|
import org.jetbrains.kotlin.idea.util.IJLoggerAdapter
|
||||||
import org.jetbrains.kotlin.library.*
|
import org.jetbrains.kotlin.library.*
|
||||||
|
import org.jetbrains.kotlin.library.impl.BuiltInsPlatform
|
||||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind
|
import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind
|
||||||
@@ -110,20 +111,25 @@ val VirtualFile.isMetadataKlib: Boolean
|
|||||||
fun checkComponent(componentFile: VirtualFile): Boolean {
|
fun checkComponent(componentFile: VirtualFile): Boolean {
|
||||||
val manifestFile = componentFile.findChild(KLIB_MANIFEST_FILE_NAME)?.takeIf { !it.isDirectory } ?: return false
|
val manifestFile = componentFile.findChild(KLIB_MANIFEST_FILE_NAME)?.takeIf { !it.isDirectory } ?: return false
|
||||||
|
|
||||||
// native libraries
|
|
||||||
val irFile = componentFile.findChild(KLIB_IR_FOLDER_NAME)
|
|
||||||
if (irFile != null && irFile.children.isNotEmpty()) return false
|
|
||||||
|
|
||||||
val manifestProperties = try {
|
val manifestProperties = try {
|
||||||
manifestFile.inputStream.use { Properties().apply { load(it) } }
|
manifestFile.inputStream.use { Properties().apply { load(it) } }
|
||||||
} catch (_: IOException) {
|
} catch (_: IOException) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return manifestProperties.containsKey(KLIB_PROPERTY_UNIQUE_NAME)
|
if (!manifestProperties.containsKey(KLIB_PROPERTY_UNIQUE_NAME)) return false
|
||||||
|
|
||||||
|
// No builtins_platform property => either a new common klib (we don't write builtins_platform for common) or old Native klib
|
||||||
|
return manifestProperties.getProperty(KLIB_PROPERTY_BUILTINS_PLATFORM) == null && !componentFile.isLegacyNativeKlibComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
// run check for library root too
|
// run check for library root too
|
||||||
// this is necessary to recognize old style KLIBs that do not have components, and report them to user appropriately
|
// this is necessary to recognize old style KLIBs that do not have components, and report them to user appropriately
|
||||||
return checkComponent(this) || children?.any(::checkComponent) == true
|
return checkComponent(this) || children?.any(::checkComponent) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val VirtualFile.isLegacyNativeKlibComponent: Boolean
|
||||||
|
get() {
|
||||||
|
val irFolder = findChild(KLIB_IR_FOLDER_NAME)
|
||||||
|
return irFolder != null && irFolder.children.isNotEmpty()
|
||||||
|
}
|
||||||
|
|||||||
@@ -90,21 +90,30 @@ internal val VirtualFile.isKonanLibraryRoot: Boolean
|
|||||||
fun checkComponent(componentFile: VirtualFile): Boolean {
|
fun checkComponent(componentFile: VirtualFile): Boolean {
|
||||||
val manifestFile = componentFile.findChild(KLIB_MANIFEST_FILE_NAME)?.takeIf { !it.isDirectory } ?: return false
|
val manifestFile = componentFile.findChild(KLIB_MANIFEST_FILE_NAME)?.takeIf { !it.isDirectory } ?: return false
|
||||||
|
|
||||||
// this is a hacky way to determine whether this is a Kotlin/Native .klib or common .klib (common .klibs don't have ir)
|
|
||||||
// TODO(dsavvinov): introduce more robust way to detect library platform
|
|
||||||
val irFolder = componentFile.findChild(KLIB_IR_FOLDER_NAME)
|
|
||||||
if (irFolder == null || irFolder.children.isEmpty()) return false
|
|
||||||
|
|
||||||
val manifestProperties = try {
|
val manifestProperties = try {
|
||||||
manifestFile.inputStream.use { Properties().apply { load(it) } }
|
manifestFile.inputStream.use { Properties().apply { load(it) } }
|
||||||
} catch (_: IOException) {
|
} catch (_: IOException) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return manifestProperties.getProperty(KLIB_PROPERTY_BUILTINS_PLATFORM) == BuiltInsPlatform.NATIVE.name
|
if (!manifestProperties.containsKey(KLIB_PROPERTY_UNIQUE_NAME)) return false
|
||||||
|
|
||||||
|
// No builtins_platform property => either a new common klib (we don't write builtins_platform for common) or old Native klib
|
||||||
|
val builtInsPlatformProperty = manifestProperties.getProperty(KLIB_PROPERTY_BUILTINS_PLATFORM)
|
||||||
|
?: return componentFile.isLegacyNativeKlibComponent // TODO(dsavvinov): drop additional legacy check after 1.4
|
||||||
|
|
||||||
|
val builtInsPlatform = BuiltInsPlatform.parseFromString(builtInsPlatformProperty) ?: return false
|
||||||
|
|
||||||
|
return builtInsPlatform == BuiltInsPlatform.NATIVE
|
||||||
}
|
}
|
||||||
|
|
||||||
// run check for library root too
|
// run check for library root too
|
||||||
// this is necessary to recognize old style KLIBs that do not have components, and report tem to user appropriately
|
// this is necessary to recognize old style KLIBs that do not have components, and report tem to user appropriately
|
||||||
return checkComponent(this) || children?.any(::checkComponent) == true
|
return checkComponent(this) || children?.any(::checkComponent) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val VirtualFile.isLegacyNativeKlibComponent: Boolean
|
||||||
|
get() {
|
||||||
|
val irFolder = findChild(KLIB_IR_FOLDER_NAME)
|
||||||
|
return irFolder != null && irFolder.children.isNotEmpty()
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user