From 59e84e826bbf13254dbf04b232dd7afe0b07b451 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Tue, 24 Dec 2019 17:29:25 +0700 Subject: [PATCH] Fast check of Kotlin/Native KLIBs by virtual files --- .../ide/konan/KotlinNativePluginUtil.kt | 23 +++++++++++++++++++ .../kotlin/ide/konan/NativeLibraryType.kt | 10 ++------ .../ide/konan/NativePlatformKindResolution.kt | 23 +++---------------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativePluginUtil.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativePluginUtil.kt index 6a6cc477f98..5cd01d906aa 100644 --- a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativePluginUtil.kt +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativePluginUtil.kt @@ -19,12 +19,17 @@ import org.jetbrains.kotlin.ide.konan.decompiler.KotlinNativeLoadingMetadataCach import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter +import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION +import org.jetbrains.kotlin.library.KLIB_MANIFEST_FILE_NAME +import org.jetbrains.kotlin.library.KLIB_PROPERTY_UNIQUE_NAME import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.impl.KotlinLibraryImpl import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf import org.jetbrains.kotlin.library.metadata.PackageAccessHandler import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes +import java.io.IOException +import java.util.* import org.jetbrains.kotlin.konan.file.File as KFile fun createFileStub(project: Project, text: String): PsiFileStub<*> { @@ -76,3 +81,21 @@ internal object CachingIdeKonanLibraryMetadataLoader : PackageAccessHandler { get() = (this as KotlinLibraryImpl).base.access.layout.isZipped } +internal val VirtualFile.isKonanLibraryRoot: Boolean + get() { + // The virtual file for a library packed in a ZIP file will have path like "/some/path/to/the/file.klib!/", + // and therefore will be recognized by VFS as a directory (isDirectory == true). + // So, first, let's check the extension. + val extension = extension + if (!extension.isNullOrEmpty() && extension != KLIB_FILE_EXTENSION) return false + + val manifestFile = findChild(KLIB_MANIFEST_FILE_NAME)?.takeIf { !it.isDirectory } ?: return false + + val manifestProperties = try { + manifestFile.inputStream.use { Properties().apply { load(it) } } + } catch (_: IOException) { + return false + } + + return manifestProperties.containsKey(KLIB_PROPERTY_UNIQUE_NAME) + } diff --git a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativeLibraryType.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativeLibraryType.kt index 46c090666d8..a1dfa8fdc07 100644 --- a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativeLibraryType.kt +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativeLibraryType.kt @@ -10,10 +10,7 @@ import com.intellij.openapi.roots.libraries.DummyLibraryProperties import com.intellij.openapi.roots.libraries.LibraryType import com.intellij.openapi.roots.libraries.ui.LibraryEditorComponent import com.intellij.openapi.vfs.VirtualFile -import com.intellij.util.PathUtil import org.jetbrains.kotlin.idea.KotlinIcons -import org.jetbrains.kotlin.konan.library.lite.LiteKonanLibraryFacade -import java.io.File import javax.swing.Icon import javax.swing.JComponent @@ -25,13 +22,10 @@ object NativeLibraryType : LibraryType(NativeLibraryKind // Library type is determined by `KotlinGradleLibraryDataService` for every library dependency imported from Gradle to IDE. // However this does not work for libraries that are to be just created during project build, e.g. C-interop Kotlin/Native KLIBs. // The code below helps to perform postponed detection of Kotlin/Native libraries. - override fun detect(classesRoots: List): DummyLibraryProperties? { - val path = classesRoots.firstOrNull()?.let { PathUtil.getLocalPath(it) } ?: return null - - return if (LiteKonanLibraryFacade.getLibraryProvider().getLibrary(File(path)) != null) + override fun detect(classesRoots: List): DummyLibraryProperties? = + if (classesRoots.firstOrNull()?.isKonanLibraryRoot == true) DummyLibraryProperties.INSTANCE!! else null - } override fun getIcon(properties: DummyLibraryProperties?): Icon = KotlinIcons.NATIVE } diff --git a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt index 3dd3ec42706..48239055614 100644 --- a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt @@ -9,7 +9,6 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.roots.libraries.PersistentLibraryKind -import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.util.PathUtil import org.jetbrains.kotlin.analyzer.ModuleInfo @@ -41,8 +40,9 @@ import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME import org.jetbrains.kotlin.konan.library.KonanFactories -import org.jetbrains.kotlin.library.* +import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.impl.createKotlinLibrary +import org.jetbrains.kotlin.library.isInterop import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind import org.jetbrains.kotlin.platform.konan.KonanPlatforms @@ -100,24 +100,7 @@ class NativePlatformKindResolution : IdePlatformKindResolution { ) } - override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean { - return when { - // The virtual file for a library packed in a ZIP file will have path like "/some/path/to/the/file.klib!/", - // and therefore will be recognized by VFS as a directory (isDirectory == true). - // So, first, let's check the extension. - virtualFile.extension == KLIB_FILE_EXTENSION -> true - - virtualFile.isDirectory -> { - val linkdataDir = virtualFile.findChild("linkdata") ?: return false - // False means we hit .knm file - !VfsUtil.processFilesRecursively(linkdataDir) { - it.extension != KLIB_METADATA_FILE_EXTENSION - } - } - - else -> false - } - } + override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean = virtualFile.isKonanLibraryRoot override fun createResolverForModuleFactory( settings: PlatformAnalysisParameters,