Fast check of Kotlin/Native KLIBs by virtual files
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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<DummyLibraryProperties>(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<VirtualFile>): DummyLibraryProperties? {
|
||||
val path = classesRoots.firstOrNull()?.let { PathUtil.getLocalPath(it) } ?: return null
|
||||
|
||||
return if (LiteKonanLibraryFacade.getLibraryProvider().getLibrary(File(path)) != null)
|
||||
override fun detect(classesRoots: List<VirtualFile>): DummyLibraryProperties? =
|
||||
if (classesRoots.firstOrNull()?.isKonanLibraryRoot == true)
|
||||
DummyLibraryProperties.INSTANCE!!
|
||||
else null
|
||||
}
|
||||
|
||||
override fun getIcon(properties: DummyLibraryProperties?): Icon = KotlinIcons.NATIVE
|
||||
}
|
||||
|
||||
+3
-20
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user