diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CommonPlatformKindResolution.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CommonPlatformKindResolution.kt index 05c5c9d80dc..341362bff65 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CommonPlatformKindResolution.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CommonPlatformKindResolution.kt @@ -16,8 +16,6 @@ import org.jetbrains.kotlin.analyzer.PlatformAnalysisParameters import org.jetbrains.kotlin.analyzer.ResolverForModuleFactory import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory -import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion -import org.jetbrains.kotlin.backend.common.serialization.metadata.metadataVersion import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.context.ProjectContext @@ -25,6 +23,7 @@ import org.jetbrains.kotlin.idea.caches.project.LibraryInfo import org.jetbrains.kotlin.idea.caches.project.SdkInfo import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey import org.jetbrains.kotlin.idea.framework.CommonLibraryKind +import org.jetbrains.kotlin.idea.klib.getCompatibilityInfo import org.jetbrains.kotlin.idea.util.IJLoggerAdapter import org.jetbrains.kotlin.library.* import org.jetbrains.kotlin.platform.CommonPlatforms @@ -83,50 +82,23 @@ class CommonPlatformKindResolution : IdePlatformKindResolution { // TODO(dsavvinov): unify with NativeLibraryInfo class CommonKlibLibraryInfo(project: Project, library: Library, val libraryRoot: String) : LibraryInfo(project, library) { - sealed class MetadataInfo { - abstract val isCompatible: Boolean - - object Compatible : MetadataInfo() { - override val isCompatible get() = true - } - - class Incompatible(val isOlder: Boolean) : MetadataInfo() { - override val isCompatible get() = false - } - } - val commonLibrary = resolveSingleFileKlib( libraryFile = KFile(libraryRoot), logger = LOG, strategy = ToolingSingleFileKlibResolveStrategy ) - val metadataInfo by lazy { - val metadataVersion = commonLibrary.safeMetadataVersion - when { - metadataVersion == null -> MetadataInfo.Incompatible(true) // too old KLIB format, even doesn't have metadata version - !metadataVersion.isCompatible() -> MetadataInfo.Incompatible(!metadataVersion.isAtLeast(KlibMetadataVersion.INSTANCE)) - else -> MetadataInfo.Compatible - } - } + val compatibilityInfo by lazy { commonLibrary.getCompatibilityInfo() } override fun getLibraryRoots() = listOf(libraryRoot) override val platform: TargetPlatform get() = CommonPlatforms.defaultCommonPlatform - override fun toString() = "Common" + super.toString() + override fun toString() = "CommonKlib" + super.toString() companion object { private val LOG = IJLoggerAdapter.getInstance(CommonKlibLibraryInfo::class.java) - - internal val KotlinLibrary.safeMetadataVersion get() = this.readSafe(null) { metadataVersion } - - private fun KotlinLibrary.readSafe(defaultValue: T, action: KotlinLibrary.() -> T) = try { - action() - } catch (_: IOException) { - defaultValue - } } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CompositeResolverForModuleFactory.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CompositeResolverForModuleFactory.kt index b6149809a24..84deeb1b03b 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CompositeResolverForModuleFactory.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/caches/resolve/CompositeResolverForModuleFactory.kt @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters import org.jetbrains.kotlin.analyzer.common.configureCommonSpecificComponents import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.container.* import org.jetbrains.kotlin.context.ModuleContext import org.jetbrains.kotlin.descriptors.ModuleDescriptor @@ -54,7 +53,6 @@ import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil import org.jetbrains.kotlin.serialization.js.createKotlinJavascriptPackageFragmentProvider import org.jetbrains.kotlin.serialization.konan.NullFlexibleTypeDeserializer import org.jetbrains.kotlin.serialization.konan.impl.KlibMetadataModuleDescriptorFactoryImpl -import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils @@ -132,7 +130,7 @@ class CompositeResolverForModuleFactory( val metadataProvder = container.get() var klibMetadataProvider: PackageFragmentProvider? = null - if (moduleInfo is CommonKlibLibraryInfo && moduleInfo.metadataInfo == CommonKlibLibraryInfo.MetadataInfo.Compatible) { + if (moduleInfo is CommonKlibLibraryInfo && moduleInfo.compatibilityInfo.isCompatible) { val library = moduleInfo.commonLibrary val languageVersionSettings = container.get() diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/klib/KlibCompatibilityInfo.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/klib/KlibCompatibilityInfo.kt new file mode 100644 index 00000000000..0a74b40ef5b --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/klib/KlibCompatibilityInfo.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.klib + +import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion +import org.jetbrains.kotlin.backend.common.serialization.metadata.metadataVersion +import org.jetbrains.kotlin.idea.klib.KlibCompatibilityInfo.* +import org.jetbrains.kotlin.library.KotlinLibrary + +/** + * Whether a certain KLIB is compatible for the purposes of IDE: indexation, resolve, etc. + */ +sealed class KlibCompatibilityInfo(val isCompatible: Boolean) { + object Compatible : KlibCompatibilityInfo(true) + object Pre14Layout : KlibCompatibilityInfo(false) + class IncompatibleMetadata(val isOlder: Boolean) : KlibCompatibilityInfo(false) +} + +fun KotlinLibrary.getCompatibilityInfo(): KlibCompatibilityInfo { + val hasPre14Manifest = readSafe(false) { has_pre_1_4_manifest } + if (hasPre14Manifest) + return Pre14Layout + + val metadataVersion = readSafe(null) { metadataVersion } + return when { + metadataVersion == null -> IncompatibleMetadata(true) // too old KLIB format, even doesn't have metadata version + !metadataVersion.isCompatible() -> IncompatibleMetadata(!metadataVersion.isAtLeast(KlibMetadataVersion.INSTANCE)) + else -> Compatible + } +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/klib/utils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/klib/utils.kt new file mode 100644 index 00000000000..d9d2359b49d --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/klib/utils.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.klib + +import org.jetbrains.kotlin.library.KotlinLibrary +import java.io.IOException + +fun KotlinLibrary.readSafe(defaultValue: T, action: KotlinLibrary.() -> T) = try { + action() +} catch (_: IOException) { + defaultValue +} diff --git a/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt b/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt index 533a363b75c..4c161f40ff3 100644 --- a/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt +++ b/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.configuration.klib.KotlinNativeLibraryNameUtil import org.jetbrains.kotlin.idea.versions.UnsupportedAbiVersionNotificationPanelProvider import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME +import org.jetbrains.kotlin.idea.klib.KlibCompatibilityInfo.IncompatibleMetadata /** TODO: merge [KotlinNativeABICompatibilityChecker] in the future with [UnsupportedAbiVersionNotificationPanelProvider], KT-34525 */ class KotlinNativeABICompatibilityChecker(private val project: Project) : ProjectComponent, Disposable { @@ -86,7 +87,7 @@ class KotlinNativeABICompatibilityChecker(private val project: Project) : Projec private fun getLibrariesToNotifyAbout(): Map { val incompatibleLibraries = getModuleInfosFromIdeaModel(project).asSequence() .filterIsInstance() - .filter { !it.metadataInfo.isCompatible } + .filter { !it.compatibilityInfo.isCompatible } .associateBy { it.libraryRoot } val newEntries = if (cachedIncompatibleLibraries.isNotEmpty()) @@ -106,7 +107,7 @@ class KotlinNativeABICompatibilityChecker(private val project: Project) : Projec val librariesByGroups = HashMap, MutableList>>() librariesToNotify.forEach { (libraryRoot, libraryInfo) -> - val isOldMetadata = (libraryInfo.metadataInfo as? NativeLibraryInfo.MetadataInfo.Incompatible)?.isOlder ?: true + val isOldMetadata = (libraryInfo.compatibilityInfo as? IncompatibleMetadata)?.isOlder ?: true val (libraryName, libraryGroup) = parseIDELibraryName(libraryInfo) librariesByGroups.computeIfAbsent(libraryGroup to isOldMetadata) { mutableListOf() } += libraryName to libraryRoot } diff --git a/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt.192 b/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt.192 index cfe68061ce5..3396d26f846 100644 --- a/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt.192 +++ b/idea/idea-gradle-native/src/org/jetbrains/kotlin/ide/konan/KotlinNativeABICompatibilityChecker.kt.192 @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.configuration.klib.KotlinNativeLibraryNameUtil import org.jetbrains.kotlin.idea.versions.UnsupportedAbiVersionNotificationPanelProvider import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME +import org.jetbrains.kotlin.idea.klib.KlibCompatibilityInfo.IncompatibleMetadata /** TODO: merge [KotlinNativeABICompatibilityChecker] in the future with [UnsupportedAbiVersionNotificationPanelProvider], KT-34525 */ class KotlinNativeABICompatibilityChecker(private val project: Project) : ProjectComponent, Disposable { @@ -87,7 +88,7 @@ class KotlinNativeABICompatibilityChecker(private val project: Project) : Projec private fun getLibrariesToNotifyAbout(): Map { val incompatibleLibraries = getModuleInfosFromIdeaModel(project).asSequence() .filterIsInstance() - .filter { !it.metadataInfo.isCompatible } + .filter { !it.compatibilityInfo.isCompatible } .associateBy { it.libraryRoot } val newEntries = if (cachedIncompatibleLibraries.isNotEmpty()) @@ -107,7 +108,7 @@ class KotlinNativeABICompatibilityChecker(private val project: Project) : Projec val librariesByGroups = HashMap, MutableList>>() librariesToNotify.forEach { (libraryRoot, libraryInfo) -> - val isOldMetadata = (libraryInfo.metadataInfo as? NativeLibraryInfo.MetadataInfo.Incompatible)?.isOlder ?: true + val isOldMetadata = (libraryInfo.compatibilityInfo as? IncompatibleMetadata)?.isOlder ?: true val (libraryName, libraryGroup) = parseIDELibraryName(libraryInfo) librariesByGroups.computeIfAbsent(libraryGroup to isOldMetadata) { mutableListOf() } += libraryName to libraryRoot } 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 51b419b1803..f22acbbc031 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 @@ -15,8 +15,6 @@ import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.analyzer.PlatformAnalysisParameters import org.jetbrains.kotlin.analyzer.ResolverForModuleFactory import org.jetbrains.kotlin.analyzer.getCapability -import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion -import org.jetbrains.kotlin.backend.common.serialization.metadata.metadataVersion import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider @@ -29,9 +27,6 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentProvider import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin -import org.jetbrains.kotlin.ide.konan.NativeLibraryInfo.Companion.safeMetadataVersion -import org.jetbrains.kotlin.ide.konan.NativeLibraryInfo.MetadataInfo.Compatible -import org.jetbrains.kotlin.ide.konan.NativeLibraryInfo.MetadataInfo.Incompatible import org.jetbrains.kotlin.ide.konan.analyzer.NativeResolverForModuleFactory import org.jetbrains.kotlin.idea.caches.project.LibraryInfo import org.jetbrains.kotlin.idea.caches.project.SdkInfo @@ -55,7 +50,8 @@ import org.jetbrains.kotlin.resolve.TargetEnvironment import org.jetbrains.kotlin.serialization.konan.NullFlexibleTypeDeserializer import org.jetbrains.kotlin.serialization.konan.impl.KlibMetadataModuleDescriptorFactoryImpl import org.jetbrains.kotlin.storage.StorageManager -import java.io.IOException +import org.jetbrains.kotlin.idea.klib.getCompatibilityInfo +import org.jetbrains.kotlin.idea.klib.readSafe private val NativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer) @@ -64,7 +60,7 @@ fun KotlinLibrary.createPackageFragmentProvider( languageVersionSettings: LanguageVersionSettings, moduleDescriptor: ModuleDescriptor ): PackageFragmentProvider? { - if (safeMetadataVersion?.isCompatible() != true) return null + if (!getCompatibilityInfo().isCompatible) return null val libraryProto = CachingIdeKonanLibraryMetadataLoader.loadModuleHeader(this) @@ -177,22 +173,10 @@ private fun createKotlinNativeBuiltIns(moduleInfo: ModuleInfo, projectContext: P private fun ModuleInfo.findNativeStdlib(): NativeLibraryInfo? = dependencies().lazyClosure { it.dependencies() } .filterIsInstance() - .firstOrNull { it.isStdlib && it.metadataInfo.isCompatible } + .firstOrNull { it.isStdlib && it.compatibilityInfo.isCompatible } class NativeLibraryInfo(project: Project, library: Library, val libraryRoot: String) : LibraryInfo(project, library) { - sealed class MetadataInfo { - abstract val isCompatible: Boolean - - object Compatible : MetadataInfo() { - override val isCompatible get() = true - } - - class Incompatible(val isOlder: Boolean) : MetadataInfo() { - override val isCompatible get() = false - } - } - private val nativeLibrary = resolveSingleFileKlib( libraryFile = KFile(libraryRoot), logger = LOG, @@ -201,14 +185,7 @@ class NativeLibraryInfo(project: Project, library: Library, val libraryRoot: Str val isStdlib get() = libraryRoot.endsWith(KONAN_STDLIB_NAME) - val metadataInfo by lazy { - val metadataVersion = nativeLibrary.safeMetadataVersion - when { - metadataVersion == null -> Incompatible(true) // too old KLIB format, even doesn't have metadata version - !metadataVersion.isCompatible() -> Incompatible(!metadataVersion.isAtLeast(KlibMetadataVersion.INSTANCE)) - else -> Compatible - } - } + val compatibilityInfo by lazy { nativeLibrary.getCompatibilityInfo() } override fun getLibraryRoots() = listOf(libraryRoot) @@ -230,13 +207,5 @@ class NativeLibraryInfo(project: Project, library: Library, val libraryRoot: Str private val LOG = IJLoggerAdapter.getInstance(NativeLibraryInfo::class.java) val NATIVE_LIBRARY_CAPABILITY = ModuleDescriptor.Capability("KotlinNativeLibrary") - - internal val KotlinLibrary.safeMetadataVersion get() = this.readSafe(null) { metadataVersion } - - private fun KotlinLibrary.readSafe(defaultValue: T, action: KotlinLibrary.() -> T) = try { - action() - } catch (_: IOException) { - defaultValue - } } }