Choose SDK consistently at least for non-COMPOSITE analysis

In COMPOSITE analysis we don't have a constant SDK dependency for whole
ResolutionFacade, so we have to find it manually via calling
'findSdkAcrossDependencies'

In SEPARATE mode we do have such a constant SDK dependency, but there
was an assumption that it doesn't make a difference (i.e.
findSdkAcrossDependencies always return the same SDK as passed constant
one)

Turns out that assumption was wrong, particularly for projects with
duplicate SDK entries in project structure. Then we would choose one SDK
in some cases, and the other one on other cases - even though they a
bit-to-bit equal, we will create separate descriptors for them, which
might lead to some issues, like in KT-34802

^KT-34802 Fixed
This commit is contained in:
Dmitry Savvinov
2019-11-21 12:27:23 +03:00
parent e4afbae954
commit 0dc7c37b62
6 changed files with 20 additions and 17 deletions
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.context.ProjectContext import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind
@@ -34,7 +35,7 @@ class CommonPlatformKindResolution : IdePlatformKindResolution {
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo): BuiltInsCacheKey = BuiltInsCacheKey.DefaultBuiltInsKey override fun getKeyForBuiltIns(moduleInfo: ModuleInfo): BuiltInsCacheKey = BuiltInsCacheKey.DefaultBuiltInsKey
override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext): KotlinBuiltIns { override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext, sdkDependency: SdkInfo?): KotlinBuiltIns {
return DefaultBuiltIns.Instance return DefaultBuiltIns.Instance
} }
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.extensions.ApplicationExtensionDescriptor import org.jetbrains.kotlin.extensions.ApplicationExtensionDescriptor
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo 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.caches.resolve.BuiltInsCacheKey
import org.jetbrains.kotlin.platform.IdePlatformKind import org.jetbrains.kotlin.platform.IdePlatformKind
import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.TargetPlatform
@@ -40,7 +41,7 @@ interface IdePlatformKindResolution {
val kind: IdePlatformKind<*> val kind: IdePlatformKind<*>
fun getKeyForBuiltIns(moduleInfo: ModuleInfo): BuiltInsCacheKey fun getKeyForBuiltIns(moduleInfo: ModuleInfo): BuiltInsCacheKey
fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext): KotlinBuiltIns fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext, sdkDependency: SdkInfo?): KotlinBuiltIns
fun createResolverForModuleFactory( fun createResolverForModuleFactory(
settings: PlatformAnalysisParameters, settings: PlatformAnalysisParameters,
@@ -13,10 +13,10 @@ import org.jetbrains.kotlin.analyzer.ResolverForModuleFactory
import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.context.ProjectContext import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey
import org.jetbrains.kotlin.idea.framework.JSLibraryKind import org.jetbrains.kotlin.idea.framework.JSLibraryKind
import org.jetbrains.kotlin.js.resolve.JsResolverForModuleFactory import org.jetbrains.kotlin.js.resolve.JsResolverForModuleFactory
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind
import org.jetbrains.kotlin.resolve.TargetEnvironment import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.TargetPlatform
@@ -35,7 +35,7 @@ class JsPlatformKindResolution : IdePlatformKindResolution {
return BuiltInsCacheKey.DefaultBuiltInsKey return BuiltInsCacheKey.DefaultBuiltInsKey
} }
override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext): KotlinBuiltIns { override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext, sdkDependency: SdkInfo?): KotlinBuiltIns {
return DefaultBuiltIns.Instance return DefaultBuiltIns.Instance
} }
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
import org.jetbrains.kotlin.context.ProjectContext import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
import org.jetbrains.kotlin.idea.caches.project.findSdkAcrossDependencies import org.jetbrains.kotlin.idea.caches.project.findSdkAcrossDependencies
import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey
import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.TargetPlatform
@@ -46,10 +47,8 @@ class JvmPlatformKindResolution : IdePlatformKindResolution {
return if (sdkInfo != null) CacheKeyBySdk(sdkInfo.sdk) else BuiltInsCacheKey.DefaultBuiltInsKey return if (sdkInfo != null) CacheKeyBySdk(sdkInfo.sdk) else BuiltInsCacheKey.DefaultBuiltInsKey
} }
override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext): KotlinBuiltIns { override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext, sdkDependency: SdkInfo?): KotlinBuiltIns {
val sdk = moduleInfo.findSdkAcrossDependencies() return if (sdkDependency != null)
return if (sdk != null)
JvmBuiltIns(projectContext.storageManager, JvmBuiltIns.Kind.FROM_CLASS_LOADER) JvmBuiltIns(projectContext.storageManager, JvmBuiltIns.Kind.FROM_CLASS_LOADER)
else else
DefaultBuiltIns.Instance DefaultBuiltIns.Instance
@@ -18,10 +18,9 @@ import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.context.withModule import org.jetbrains.kotlin.context.withModule
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.idea.caches.project.*
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.findSdkAcrossDependencies
import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo
import org.jetbrains.kotlin.idea.caches.project.getPlatformModuleInfo
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
import org.jetbrains.kotlin.idea.project.IdeaEnvironment import org.jetbrains.kotlin.idea.project.IdeaEnvironment
import org.jetbrains.kotlin.idea.project.findAnalyzerServices import org.jetbrains.kotlin.idea.project.findAnalyzerServices
@@ -45,7 +44,7 @@ class IdeaResolverForProject(
fallbackModificationTracker: ModificationTracker? = null, fallbackModificationTracker: ModificationTracker? = null,
private val isReleaseCoroutines: Boolean? = null, private val isReleaseCoroutines: Boolean? = null,
// TODO(dsavvinov): this is needed only for non-composite analysis, extract separate resolver implementation instead // TODO(dsavvinov): this is needed only for non-composite analysis, extract separate resolver implementation instead
private val constantSdkDependencyIfAny: IdeaModuleInfo? = null private val constantSdkDependencyIfAny: SdkInfo? = null
) : AbstractResolverForProject<IdeaModuleInfo>( ) : AbstractResolverForProject<IdeaModuleInfo>(
debugName, debugName,
projectContext, projectContext,
@@ -54,9 +53,10 @@ class IdeaResolverForProject(
delegateResolver, delegateResolver,
ServiceManager.getService(projectContext.project, IdePackageOracleFactory::class.java) ServiceManager.getService(projectContext.project, IdePackageOracleFactory::class.java)
) { ) {
private val builtInsCache: BuiltInsCache = (delegateResolver as? IdeaResolverForProject)?.builtInsCache ?: BuiltInsCache(projectContext, this) private val builtInsCache: BuiltInsCache =
(delegateResolver as? IdeaResolverForProject)?.builtInsCache ?: BuiltInsCache(projectContext, this)
override fun sdkDependency(module: IdeaModuleInfo): IdeaModuleInfo? { override fun sdkDependency(module: IdeaModuleInfo): SdkInfo? {
if (projectContext.project.useCompositeAnalysis) { if (projectContext.project.useCompositeAnalysis) {
require(constantSdkDependencyIfAny == null) { "Shouldn't pass SDK dependency manually for composite analysis mode" } require(constantSdkDependencyIfAny == null) { "Shouldn't pass SDK dependency manually for composite analysis mode" }
} }
@@ -129,13 +129,13 @@ class IdeaResolverForProject(
// Note #1: we can't use .getOrPut, because we have to put builtIns into map *before* initialization // Note #1: we can't use .getOrPut, because we have to put builtIns into map *before* initialization
// Note #2: it's OK to put not-initialized built-ins into public map, because access to [cache] is guarded by storageManager.lock // Note #2: it's OK to put not-initialized built-ins into public map, because access to [cache] is guarded by storageManager.lock
val newBuiltIns = module.platform.idePlatformKind.resolution.createBuiltIns(module, projectContextFromSdkResolver) val sdk = resolverForSdk.sdkDependency(module)
val newBuiltIns = module.platform.idePlatformKind.resolution.createBuiltIns(module, projectContextFromSdkResolver, sdk)
cache[key] = newBuiltIns cache[key] = newBuiltIns
if (newBuiltIns is JvmBuiltIns) { if (newBuiltIns is JvmBuiltIns) {
// SDK should be present, otherwise we wouldn't have created JvmBuiltIns in createBuiltIns // SDK should be present, otherwise we wouldn't have created JvmBuiltIns in createBuiltIns
val sdk = module.findSdkAcrossDependencies()!! val sdkDescriptor = resolverForSdk.descriptorForModule(sdk!!)
val sdkDescriptor = resolverForSdk.descriptorForModule(sdk)
val isAdditionalBuiltInsFeaturesSupported = module.supportsAdditionalBuiltInsMembers(projectContextFromSdkResolver.project) val isAdditionalBuiltInsFeaturesSupported = module.supportsAdditionalBuiltInsMembers(projectContextFromSdkResolver.project)
@@ -30,7 +30,9 @@ import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin
import org.jetbrains.kotlin.ide.konan.NativeLibraryInfo.Companion.safeAbiVersion import org.jetbrains.kotlin.ide.konan.NativeLibraryInfo.Companion.safeAbiVersion
import org.jetbrains.kotlin.ide.konan.NativeLibraryInfo.Companion.isCompatible import org.jetbrains.kotlin.ide.konan.NativeLibraryInfo.Companion.isCompatible
import org.jetbrains.kotlin.ide.konan.analyzer.NativeResolverForModuleFactory import org.jetbrains.kotlin.ide.konan.analyzer.NativeResolverForModuleFactory
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
import org.jetbrains.kotlin.idea.caches.project.lazyClosure import org.jetbrains.kotlin.idea.caches.project.lazyClosure
import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
@@ -130,7 +132,7 @@ class NativePlatformKindResolution : IdePlatformKindResolution {
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo): BuiltInsCacheKey = NativeBuiltInsCacheKey override fun getKeyForBuiltIns(moduleInfo: ModuleInfo): BuiltInsCacheKey = NativeBuiltInsCacheKey
override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext) = override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext, sdkDependency: SdkInfo?) =
createKotlinNativeBuiltIns(moduleInfo, projectContext) createKotlinNativeBuiltIns(moduleInfo, projectContext)
object NativeBuiltInsCacheKey : BuiltInsCacheKey object NativeBuiltInsCacheKey : BuiltInsCacheKey