IDE: Fix ToolingSingleFileKlibResolveStrategy to recongnize klib archives
Issue #KT-36213
This commit is contained in:
@@ -6,8 +6,11 @@
|
|||||||
package org.jetbrains.kotlin.library
|
package org.jetbrains.kotlin.library
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
|
import org.jetbrains.kotlin.konan.file.file
|
||||||
|
import org.jetbrains.kotlin.konan.file.withZipFileSystem
|
||||||
import org.jetbrains.kotlin.library.impl.createKotlinLibrary
|
import org.jetbrains.kotlin.library.impl.createKotlinLibrary
|
||||||
import org.jetbrains.kotlin.util.Logger
|
import org.jetbrains.kotlin.util.Logger
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves KLIB library by making sure that the library has 1.4+ layout with exactly one component.
|
* Resolves KLIB library by making sure that the library has 1.4+ layout with exactly one component.
|
||||||
@@ -23,32 +26,61 @@ import org.jetbrains.kotlin.util.Logger
|
|||||||
* Typical usage scenario: IDE.
|
* Typical usage scenario: IDE.
|
||||||
*/
|
*/
|
||||||
object ToolingSingleFileKlibResolveStrategy : SingleFileKlibResolveStrategy {
|
object ToolingSingleFileKlibResolveStrategy : SingleFileKlibResolveStrategy {
|
||||||
override fun resolve(libraryFile: File, logger: Logger): KotlinLibrary {
|
override fun resolve(libraryFile: File, logger: Logger): KotlinLibrary =
|
||||||
if (checkComponent(libraryFile)) {
|
withSafeAccess(libraryFile) { localRoot ->
|
||||||
// old style library
|
if (localRoot.looksLikeKlibComponent) {
|
||||||
return fakeLibrary(libraryFile)
|
// old style library
|
||||||
}
|
null
|
||||||
|
} else {
|
||||||
|
val components = localRoot.listFiles.filter { it.looksLikeKlibComponent }
|
||||||
|
when (components.size) {
|
||||||
|
0 -> null
|
||||||
|
1 -> {
|
||||||
|
// single component library
|
||||||
|
createKotlinLibrary(libraryFile, components.single().name)
|
||||||
|
}
|
||||||
|
else -> { // TODO: choose the best fit among all available candidates
|
||||||
|
// mimic as old style library and warn
|
||||||
|
logger.warning("Library $libraryFile can not be read. Multiple components found: ${components.map {
|
||||||
|
it.path.substringAfter(localRoot.path)
|
||||||
|
}}")
|
||||||
|
|
||||||
val componentFiles = libraryFile.listFiles.filter(::checkComponent)
|
null
|
||||||
componentFiles.singleOrNull()?.let { componentFile ->
|
}
|
||||||
// single component library
|
}
|
||||||
return createKotlinLibrary(libraryFile, componentFile.name)
|
}
|
||||||
}
|
} ?: fakeLibrary(libraryFile)
|
||||||
|
|
||||||
// otherwise mimic as old style library and warn
|
|
||||||
if (componentFiles.isNotEmpty()) {
|
|
||||||
// TODO: choose the best fit among all available candidates
|
|
||||||
|
|
||||||
logger.warning("Library $libraryFile can not be read. Multiple components found: ${componentFiles.map {
|
|
||||||
it.path.substringAfter(libraryFile.path)
|
|
||||||
}}")
|
|
||||||
}
|
|
||||||
|
|
||||||
return fakeLibrary(libraryFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
private const val NONEXISTENT_COMPONENT_NAME = "__nonexistent_component_name__"
|
private const val NONEXISTENT_COMPONENT_NAME = "__nonexistent_component_name__"
|
||||||
|
|
||||||
private fun checkComponent(componentFile: File) = componentFile.child(KLIB_MANIFEST_FILE_NAME).isFile
|
private fun fakeLibrary(libraryFile: File): KotlinLibrary = createKotlinLibrary(libraryFile, NONEXISTENT_COMPONENT_NAME)
|
||||||
private fun fakeLibrary(libraryFile: File) = createKotlinLibrary(libraryFile, NONEXISTENT_COMPONENT_NAME)
|
|
||||||
|
private fun <T : Any> withSafeAccess(libraryFile: File, action: (localRoot: File) -> T?): T? {
|
||||||
|
val extension = libraryFile.extension
|
||||||
|
|
||||||
|
val wrappedAction: () -> T? = when {
|
||||||
|
extension == KLIB_FILE_EXTENSION -> {
|
||||||
|
if (!libraryFile.isFile) return null
|
||||||
|
|
||||||
|
{ libraryFile.withZipFileSystem { fs -> action(fs.file("/")) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension.isNotEmpty() -> return null
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
if (!libraryFile.isDirectory) return null
|
||||||
|
|
||||||
|
{ action(libraryFile) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return try {
|
||||||
|
wrappedAction()
|
||||||
|
} catch (_: IOException) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val File.looksLikeKlibComponent: Boolean
|
||||||
|
get() = child(KLIB_MANIFEST_FILE_NAME).isFile
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user