Fix: Don't analyse incompatible K/N KLIBs in IDE

Issue #KT-34159
This commit is contained in:
Dmitriy Dolovov
2019-10-18 13:18:57 +07:00
parent b1d7df697d
commit 9c887c1e79
2 changed files with 28 additions and 14 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
import org.jetbrains.kotlin.ide.konan.NativeLibraryInfo.Companion.isAbiCompatible
import org.jetbrains.kotlin.ide.konan.analyzer.NativeResolverForModuleFactory import org.jetbrains.kotlin.ide.konan.analyzer.NativeResolverForModuleFactory
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
import org.jetbrains.kotlin.idea.caches.project.lazyClosure import org.jetbrains.kotlin.idea.caches.project.lazyClosure
@@ -35,11 +36,8 @@ import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
import org.jetbrains.kotlin.konan.library.KonanFactories import org.jetbrains.kotlin.konan.library.KonanFactories
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION import org.jetbrains.kotlin.library.*
import org.jetbrains.kotlin.library.KLIB_METADATA_FILE_EXTENSION
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.impl.createKotlinLibrary import org.jetbrains.kotlin.library.impl.createKotlinLibrary
import org.jetbrains.kotlin.library.isInterop
import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
import org.jetbrains.kotlin.platform.konan.KonanPlatforms import org.jetbrains.kotlin.platform.konan.KonanPlatforms
@@ -48,12 +46,16 @@ import org.jetbrains.kotlin.resolve.ImplicitIntegerCoercion
import org.jetbrains.kotlin.resolve.TargetEnvironment import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.serialization.konan.impl.KlibMetadataModuleDescriptorFactoryImpl import org.jetbrains.kotlin.serialization.konan.impl.KlibMetadataModuleDescriptorFactoryImpl
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import java.io.IOException
import kotlin.LazyThreadSafetyMode.PUBLICATION
fun KotlinLibrary.createPackageFragmentProvider( fun KotlinLibrary.createPackageFragmentProvider(
storageManager: StorageManager, storageManager: StorageManager,
languageVersionSettings: LanguageVersionSettings, languageVersionSettings: LanguageVersionSettings,
moduleDescriptor: ModuleDescriptor moduleDescriptor: ModuleDescriptor
): PackageFragmentProvider { ): PackageFragmentProvider? {
if (!isAbiCompatible) return null
val libraryProto = CachingIdeKonanLibraryMetadataLoader.loadModuleHeader(this) val libraryProto = CachingIdeKonanLibraryMetadataLoader.loadModuleHeader(this)
@@ -183,7 +185,7 @@ private fun createKotlinNativeBuiltIns(moduleInfo: ModuleInfo, projectContext: P
private fun ModuleInfo.findNativeStdlib(): NativeLibraryInfo? = private fun ModuleInfo.findNativeStdlib(): NativeLibraryInfo? =
dependencies().lazyClosure { it.dependencies() } dependencies().lazyClosure { it.dependencies() }
.filterIsInstance<NativeLibraryInfo>() .filterIsInstance<NativeLibraryInfo>()
.firstOrNull { it.isStdlib } .firstOrNull { it.isStdlib && it.isAbiCompatible }
class NativeLibraryInfo(project: Project, library: Library, root: File) : LibraryInfo(project, library) { class NativeLibraryInfo(project: Project, library: Library, root: File) : LibraryInfo(project, library) {
@@ -191,17 +193,20 @@ class NativeLibraryInfo(project: Project, library: Library, root: File) : Librar
private val roots = listOf(root.absolutePath) private val roots = listOf(root.absolutePath)
val isStdlib by lazy { roots.first().endsWith(KONAN_STDLIB_NAME) } val isStdlib by lazy(PUBLICATION) { roots.first().endsWith(KONAN_STDLIB_NAME) }
val isAbiCompatible get() = nativeLibrary.isAbiCompatible
override fun getLibraryRoots() = roots override fun getLibraryRoots() = roots
override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?> override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
get() = super.capabilities + get() {
mapOf( val capabilities = super.capabilities.toMutableMap()
KlibModuleOrigin.CAPABILITY to this, capabilities += KlibModuleOrigin.CAPABILITY to DeserializedKlibModuleOrigin(nativeLibrary)
ImplicitIntegerCoercion.MODULE_CAPABILITY to nativeLibrary.isInterop, capabilities += NATIVE_LIBRARY_CAPABILITY to nativeLibrary
NATIVE_LIBRARY_CAPABILITY to nativeLibrary capabilities += ImplicitIntegerCoercion.MODULE_CAPABILITY to nativeLibrary.readSafe(false) { isInterop }
) return capabilities
}
override val platform: TargetPlatform override val platform: TargetPlatform
get() = KonanPlatforms.defaultKonanPlatform get() = KonanPlatforms.defaultKonanPlatform
@@ -210,5 +215,13 @@ class NativeLibraryInfo(project: Project, library: Library, root: File) : Librar
companion object { companion object {
val NATIVE_LIBRARY_CAPABILITY = ModuleDescriptor.Capability<KotlinLibrary>("KotlinNativeLibrary") val NATIVE_LIBRARY_CAPABILITY = ModuleDescriptor.Capability<KotlinLibrary>("KotlinNativeLibrary")
val KotlinLibrary.isAbiCompatible get() = this.readSafe(null) { versions.abiVersion } == KotlinAbiVersion.CURRENT
private fun <T> KotlinLibrary.readSafe(defaultValue: T, action: KotlinLibrary.() -> T) = try {
action()
} catch (_: IOException) {
defaultValue
}
} }
} }
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService.Companion.createDeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService.Companion.createDeclarationProviderFactory
import org.jetbrains.kotlin.utils.addIfNotNull
class NativeResolverForModuleFactory( class NativeResolverForModuleFactory(
private val platformAnalysisParameters: PlatformAnalysisParameters, private val platformAnalysisParameters: PlatformAnalysisParameters,
@@ -67,7 +68,7 @@ class NativeResolverForModuleFactory(
moduleDescriptor moduleDescriptor
) )
fragmentProviders.add(libPackageFragmentProvider) fragmentProviders.addIfNotNull(libPackageFragmentProvider)
} }
return ResolverForModule(CompositePackageFragmentProvider(fragmentProviders), container) return ResolverForModule(CompositePackageFragmentProvider(fragmentProviders), container)