Detect K/N library kind if library is a ZIP file (native-specific part)
Issue #KT-26730 Fixed
This commit is contained in:
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.ide.konan
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiFileFactory
|
||||
import com.intellij.psi.SingleRootFileViewProvider
|
||||
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrarySource.KonanLibraryDir
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrarySource.KonanLibraryFile
|
||||
import org.jetbrains.kotlin.konan.library.MetadataReader
|
||||
import org.jetbrains.kotlin.konan.library.createKonanLibrary
|
||||
import org.jetbrains.kotlin.konan.util.KonanFactories.DefaultPackageFragmentsFactory
|
||||
@@ -98,16 +100,31 @@ private fun KonanLibrary.createPackageFragmentProvider(
|
||||
internal object CachingIdeMetadataReaderImpl : MetadataReader {
|
||||
|
||||
override fun loadSerializedModule(libraryLayout: KonanLibraryLayout): KonanProtoBuf.LinkDataLibrary =
|
||||
cache.getCachedModuleHeader(libraryLayout.moduleHeaderFile.virtualFile)
|
||||
cache.getCachedModuleHeader(libraryLayout.getVirtualFile(libraryLayout.moduleHeaderFile))
|
||||
|
||||
override fun loadSerializedPackageFragment(
|
||||
libraryLayout: KonanLibraryLayout,
|
||||
packageFqName: String
|
||||
): KonanProtoBuf.LinkDataPackageFragment =
|
||||
cache.getCachedPackageFragment(libraryLayout.packageFragmentFile(packageFqName).virtualFile)
|
||||
cache.getCachedPackageFragment(libraryLayout.getVirtualFile(libraryLayout.packageFragmentFile(packageFqName)))
|
||||
|
||||
private val File.virtualFile: VirtualFile
|
||||
get() = LocalFileSystem.getInstance().refreshAndFindFileByPath(path) ?: error("File not found: $path")
|
||||
private fun KonanLibraryLayout.getVirtualFile(file: File): VirtualFile {
|
||||
val source = this.source
|
||||
return when (source) {
|
||||
is KonanLibraryFile -> asJarFileSystemFile(source.klibFile, file)
|
||||
is KonanLibraryDir -> asLocalFile(file)
|
||||
}
|
||||
}
|
||||
|
||||
private fun asJarFileSystemFile(jarFile: File, localFile: File): VirtualFile {
|
||||
val fullPath = jarFile.absolutePath + "!" + localFile.absolutePath
|
||||
return StandardFileSystems.jar().findFileByPath(fullPath) ?: error("File not found: $fullPath")
|
||||
}
|
||||
|
||||
private fun asLocalFile(localFile: File): VirtualFile {
|
||||
val fullPath = localFile.absolutePath
|
||||
return StandardFileSystems.local().findFileByPath(fullPath) ?: error("File not found: $fullPath")
|
||||
}
|
||||
|
||||
private val cache
|
||||
get() = KotlinNativeLoadingMetadataCache.getInstance()
|
||||
|
||||
+20
-4
@@ -9,6 +9,8 @@ import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.ApplicationComponent
|
||||
import com.intellij.openapi.vfs.*
|
||||
import com.intellij.util.containers.ContainerUtil.createConcurrentSoftValueMap
|
||||
import org.jetbrains.kotlin.konan.library.KLIB_METADATA_FILE_EXTENSION
|
||||
import org.jetbrains.kotlin.konan.library.KLIB_MODULE_METADATA_FILE_NAME
|
||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.konan.parseModuleHeader
|
||||
import org.jetbrains.kotlin.serialization.konan.parsePackageFragment
|
||||
@@ -25,12 +27,12 @@ class KotlinNativeLoadingMetadataCache : ApplicationComponent {
|
||||
private val moduleHeaderCache = createConcurrentSoftValueMap<VirtualFile, KonanProtoBuf.LinkDataLibrary>()
|
||||
|
||||
fun getCachedPackageFragment(virtualFile: VirtualFile): KonanProtoBuf.LinkDataPackageFragment =
|
||||
packageFragmentCache.computeIfAbsent(virtualFile) {
|
||||
packageFragmentCache.computeIfAbsent(virtualFile.surePackageMetadataFile) {
|
||||
parsePackageFragment(virtualFile.contentsToByteArray(false))
|
||||
}
|
||||
|
||||
fun getCachedModuleHeader(virtualFile: VirtualFile): KonanProtoBuf.LinkDataLibrary =
|
||||
moduleHeaderCache.computeIfAbsent(virtualFile) {
|
||||
moduleHeaderCache.computeIfAbsent(virtualFile.sureModuleHeaderFile) {
|
||||
parseModuleHeader(virtualFile.contentsToByteArray(false))
|
||||
}
|
||||
|
||||
@@ -45,7 +47,21 @@ class KotlinNativeLoadingMetadataCache : ApplicationComponent {
|
||||
}
|
||||
|
||||
private fun invalidateCaches(virtualFile: VirtualFile) {
|
||||
packageFragmentCache.remove(virtualFile)
|
||||
moduleHeaderCache.remove(virtualFile)
|
||||
when {
|
||||
virtualFile.isPackageMetadataFile -> packageFragmentCache.remove(virtualFile)
|
||||
virtualFile.isModuleHeaderFile -> moduleHeaderCache.remove(virtualFile)
|
||||
}
|
||||
}
|
||||
|
||||
private val VirtualFile.surePackageMetadataFile
|
||||
get() = if (isPackageMetadataFile) this else error("Not a package metadata file: $this")
|
||||
|
||||
private val VirtualFile.isPackageMetadataFile
|
||||
get() = extension == KLIB_METADATA_FILE_EXTENSION
|
||||
|
||||
private val VirtualFile.sureModuleHeaderFile
|
||||
get() = if (isModuleHeaderFile) this else error("Not a module header file: $this")
|
||||
|
||||
private val VirtualFile.isModuleHeaderFile
|
||||
get() = name == KLIB_MODULE_METADATA_FILE_NAME
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user