Fix exceptions caused by cyclic dependency between ModuleDescriptor and JvmBuiltIns

^KT-39105 Fixed
^KT-42001 Fixed

See also EA-216604 and EA-211562
This commit is contained in:
Denis.Zharkov
2020-12-22 18:26:52 +03:00
parent 5a8dc00a0d
commit 7b9f6c1560
8 changed files with 90 additions and 48 deletions
@@ -14,6 +14,7 @@ import com.intellij.util.PathUtil
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.PlatformAnalysisParameters
import org.jetbrains.kotlin.analyzer.ResolverForModuleFactory
import org.jetbrains.kotlin.analyzer.ResolverForProject
import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters
import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey
@@ -53,7 +55,12 @@ class CommonPlatformKindResolution : IdePlatformKindResolution {
override fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?): BuiltInsCacheKey = BuiltInsCacheKey.DefaultBuiltInsKey
override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext, sdkDependency: SdkInfo?): KotlinBuiltIns {
override fun createBuiltIns(
moduleInfo: IdeaModuleInfo,
projectContext: ProjectContext,
resolverForProject: ResolverForProject<IdeaModuleInfo>,
sdkDependency: SdkInfo?
): KotlinBuiltIns {
return DefaultBuiltIns.Instance
}
@@ -23,12 +23,14 @@ import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.PlatformAnalysisParameters
import org.jetbrains.kotlin.analyzer.ResolverForModuleFactory
import org.jetbrains.kotlin.analyzer.ResolverForProject
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.extensions.ApplicationExtensionDescriptor
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey
@@ -41,7 +43,12 @@ interface IdePlatformKindResolution {
val kind: IdePlatformKind<*>
fun getKeyForBuiltIns(moduleInfo: ModuleInfo, sdkInfo: SdkInfo?): BuiltInsCacheKey
fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext, sdkDependency: SdkInfo?): KotlinBuiltIns
fun createBuiltIns(
moduleInfo: IdeaModuleInfo,
projectContext: ProjectContext,
resolverForProject: ResolverForProject<IdeaModuleInfo>,
sdkDependency: SdkInfo?
): KotlinBuiltIns
fun createResolverForModuleFactory(
settings: PlatformAnalysisParameters,
@@ -88,4 +95,4 @@ interface IdePlatformKindResolution {
}
val IdePlatformKind<*>.resolution: IdePlatformKindResolution
get() = IdePlatformKindResolution.getResolution(this)
get() = IdePlatformKindResolution.getResolution(this)
@@ -14,12 +14,14 @@ import com.intellij.util.PathUtil
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.PlatformAnalysisParameters
import org.jetbrains.kotlin.analyzer.ResolverForModuleFactory
import org.jetbrains.kotlin.analyzer.ResolverForProject
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
import org.jetbrains.kotlin.idea.caches.resolve.BuiltInsCacheKey
@@ -53,7 +55,12 @@ class JsPlatformKindResolution : IdePlatformKindResolution {
return BuiltInsCacheKey.DefaultBuiltInsKey
}
override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext, sdkDependency: SdkInfo?): KotlinBuiltIns {
override fun createBuiltIns(
moduleInfo: IdeaModuleInfo,
projectContext: ProjectContext,
resolverForProject: ResolverForProject<IdeaModuleInfo>,
sdkDependency: SdkInfo?
): KotlinBuiltIns {
return DefaultBuiltIns.Instance
}
@@ -13,13 +13,16 @@ import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.PlatformAnalysisParameters
import org.jetbrains.kotlin.analyzer.ResolverForModuleFactory
import org.jetbrains.kotlin.analyzer.ResolverForProject
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
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.supportsAdditionalBuiltInsMembers
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
@@ -52,9 +55,23 @@ class JvmPlatformKindResolution : IdePlatformKindResolution {
return if (sdkInfo != null) CacheKeyBySdk(sdkInfo.sdk) else BuiltInsCacheKey.DefaultBuiltInsKey
}
override fun createBuiltIns(moduleInfo: ModuleInfo, projectContext: ProjectContext, sdkDependency: SdkInfo?): KotlinBuiltIns {
override fun createBuiltIns(
moduleInfo: IdeaModuleInfo,
projectContext: ProjectContext,
resolverForProject: ResolverForProject<IdeaModuleInfo>,
sdkDependency: SdkInfo?
): KotlinBuiltIns {
return if (sdkDependency != null)
JvmBuiltIns(projectContext.storageManager, JvmBuiltIns.Kind.FROM_CLASS_LOADER)
JvmBuiltIns(projectContext.storageManager, JvmBuiltIns.Kind.FROM_CLASS_LOADER).apply {
setPostponedSettingsComputation {
// SDK should be present, otherwise we wouldn't have created JvmBuiltIns in createBuiltIns
val sdkDescriptor = resolverForProject.descriptorForModule(sdkDependency)
val isAdditionalBuiltInsFeaturesSupported =
moduleInfo.supportsAdditionalBuiltInsMembers(projectContext.project)
JvmBuiltIns.Settings(sdkDescriptor, isAdditionalBuiltInsFeaturesSupported)
}
}
else
DefaultBuiltIns.Instance
}
@@ -10,7 +10,6 @@ import com.intellij.openapi.util.ModificationTracker
import org.jetbrains.kotlin.analyzer.*
import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
import org.jetbrains.kotlin.caches.resolve.CompositeAnalyzerServices
import org.jetbrains.kotlin.caches.resolve.CompositeResolverForModuleFactory
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
@@ -145,21 +144,12 @@ class IdeaResolverForProject(
val cachedBuiltIns = cache[key]
if (cachedBuiltIns != null) return@compute cachedBuiltIns
// 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
val newBuiltIns = module.platform.idePlatformKind.resolution.createBuiltIns(module, projectContextFromSdkResolver, sdk)
cache[key] = newBuiltIns
if (newBuiltIns is JvmBuiltIns) {
// SDK should be present, otherwise we wouldn't have created JvmBuiltIns in createBuiltIns
val sdkDescriptor = resolverForSdk.descriptorForModule(sdk!!)
val isAdditionalBuiltInsFeaturesSupported = module.supportsAdditionalBuiltInsMembers(projectContextFromSdkResolver.project)
newBuiltIns.initialize(sdkDescriptor, isAdditionalBuiltInsFeaturesSupported)
}
return@compute newBuiltIns
module.platform.idePlatformKind.resolution
.createBuiltIns(module, projectContextFromSdkResolver, resolverForSdk, sdk)
.also {
// TODO: MemoizedFunction should be used here instead, but for proper we also need a module (for LV settings) that is not contained in the key
cache[key] = it
}
}
}