Create different KotlinBuiltIns for modules with different language feature settings.
For sdkModule we create builtIns with default language feature settings. Also when we create sdkModuleResolverProvider we create builtIns cache. Then for every other module we get builtIns cached by value isAdditionalBuiltInsFeatureSupported.
This commit is contained in:
committed by
Dmitry Jemerov
parent
7c0cdf90cf
commit
e38ca44595
@@ -157,7 +157,7 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
||||
modulesContent: (M) -> ModuleContent,
|
||||
platformParameters: P,
|
||||
targetEnvironment: TargetEnvironment = CompilerEnvironment,
|
||||
builtIns: KotlinBuiltIns = DefaultBuiltIns.Instance,
|
||||
builtIns: (M) -> KotlinBuiltIns = { DefaultBuiltIns.Instance },
|
||||
delegateResolver: ResolverForProject<M> = EmptyResolverForProject(),
|
||||
packagePartProviderFactory: (M, ModuleContent) -> PackagePartProvider = { _, _ -> PackagePartProvider.Empty },
|
||||
firstDependency: M? = null,
|
||||
@@ -170,7 +170,7 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
||||
modules.forEach {
|
||||
module ->
|
||||
descriptorByModule[module] =
|
||||
ModuleDescriptorImpl(module.name, storageManager, builtIns,
|
||||
ModuleDescriptorImpl(module.name, storageManager, builtIns(module),
|
||||
modulePlatforms(module), moduleSources(module), module.capabilities)
|
||||
}
|
||||
return ResolverForProjectImpl(debugName, descriptorByModule, delegateResolver)
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() {
|
||||
val moduleName = javaClass.name.asString().toLowerCase().first().toString()
|
||||
modules.first { it._name == moduleName }
|
||||
},
|
||||
builtIns = builtIns,
|
||||
builtIns = { builtIns },
|
||||
modulePlatforms = { MultiTargetPlatform.Specific("JVM") }
|
||||
)
|
||||
|
||||
|
||||
@@ -44,7 +44,10 @@ class JvmBuiltIns @JvmOverloads constructor(
|
||||
JvmBuiltInsSettings(
|
||||
builtInsModule, storageManager,
|
||||
{ ownerModuleDescriptor.sure { "JvmBuiltins has not been initialized properly" } },
|
||||
{ isAdditionalBuiltInsFeatureSupported }
|
||||
{
|
||||
ownerModuleDescriptor.sure { "JvmBuiltins has not been initialized properly" }
|
||||
isAdditionalBuiltInsFeatureSupported
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.caches.resolve
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.util.containers.SLRUCache
|
||||
import org.jetbrains.kotlin.analyzer.LanguageSettingsProvider
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.context.GlobalContextImpl
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||
import org.jetbrains.kotlin.platform.JvmBuiltIns
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
|
||||
class BuiltInsCache private constructor(
|
||||
private val project: Project,
|
||||
platform: TargetPlatform,
|
||||
sdk: Sdk?,
|
||||
sdkModuleDescriptor: ModuleDescriptor?,
|
||||
sdkContext: GlobalContextImpl
|
||||
) {
|
||||
|
||||
private val cache: SLRUCache<Boolean, KotlinBuiltIns> = object : SLRUCache<Boolean, KotlinBuiltIns>(2, 2) {
|
||||
override fun createValue(key: Boolean): KotlinBuiltIns {
|
||||
val builtIns = calculateBuiltIns(platform, sdk, sdkContext)
|
||||
|
||||
if (builtIns is JvmBuiltIns) {
|
||||
builtIns.initialize(sdkModuleDescriptor!!, key)
|
||||
}
|
||||
return builtIns
|
||||
}
|
||||
}
|
||||
|
||||
fun getBuiltIns(moduleInfo: ModuleInfo): KotlinBuiltIns {
|
||||
val languageFeatureSettings = LanguageSettingsProvider.getInstance(project).getLanguageVersionSettings(moduleInfo)
|
||||
return cache.get(languageFeatureSettings.supportsFeature(LanguageFeature.AdditionalBuiltInsMembers))
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun calculateBuiltIns(platform: TargetPlatform, sdk: Sdk?, sdkContext: GlobalContextImpl): KotlinBuiltIns = when {
|
||||
platform is JsPlatform -> JsPlatform.builtIns
|
||||
platform is JvmPlatform && sdk != null -> JvmBuiltIns(sdkContext.storageManager)
|
||||
else -> DefaultBuiltIns.Instance
|
||||
}
|
||||
|
||||
fun createCacheAndInitializeBuiltIns(
|
||||
project: Project,
|
||||
platform: TargetPlatform,
|
||||
sdk: Sdk?,
|
||||
sdkModuleDescriptor: ModuleDescriptor?,
|
||||
sdkBuiltIns: KotlinBuiltIns,
|
||||
sdkContext: GlobalContextImpl
|
||||
): BuiltInsCache {
|
||||
val builtInsCache = BuiltInsCache(project, platform, sdk, sdkModuleDescriptor, sdkContext)
|
||||
|
||||
if (sdkBuiltIns is JvmBuiltIns) {
|
||||
val isAdditionalBuiltInsFeatureSupported = LanguageVersionSettingsImpl.DEFAULT.supportsFeature(LanguageFeature.AdditionalBuiltInsMembers)
|
||||
sdkBuiltIns.initialize(
|
||||
sdkModuleDescriptor!!, // sdk is not null for JvmBuiltIns because of calculateBuiltIns
|
||||
isAdditionalBuiltInsFeatureSupported)
|
||||
builtInsCache.cache.put(isAdditionalBuiltInsFeatureSupported, sdkBuiltIns)
|
||||
}
|
||||
return builtInsCache
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-31
@@ -29,31 +29,23 @@ import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import com.intellij.util.containers.SLRUCache
|
||||
import org.jetbrains.kotlin.analyzer.EmptyResolverForProject
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.container.get
|
||||
import org.jetbrains.kotlin.container.getService
|
||||
import org.jetbrains.kotlin.context.GlobalContext
|
||||
import org.jetbrains.kotlin.context.GlobalContextImpl
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesModificationTracker
|
||||
import org.jetbrains.kotlin.idea.project.AnalyzerFacadeProvider
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.project.outOfBlockModificationCount
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||
import org.jetbrains.kotlin.platform.JvmBuiltIns
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.KotlinSuppressCache
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.script.KotlinScriptExternalDependencies
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.sumByLong
|
||||
import java.lang.AssertionError
|
||||
@@ -377,32 +369,12 @@ private fun globalResolveSessionProvider(
|
||||
val delegateResolverProvider = reuseDataFrom?.moduleResolverProvider
|
||||
val delegateResolverForProject = delegateResolverProvider?.resolverForProject ?: EmptyResolverForProject()
|
||||
|
||||
val reusedBuiltIns = delegateResolverProvider?.builtIns
|
||||
val newBuiltIns: KotlinBuiltIns? = when {
|
||||
reusedBuiltIns != null -> null
|
||||
platform is JsPlatform -> JsPlatform.builtIns
|
||||
platform is JvmPlatform && sdk != null -> JvmBuiltIns(globalContext.storageManager)
|
||||
else -> DefaultBuiltIns.Instance
|
||||
}
|
||||
|
||||
val builtIns = reusedBuiltIns ?: newBuiltIns!!
|
||||
val moduleResolverProvider = createModuleResolverProvider(
|
||||
createModuleResolverProvider(
|
||||
debugName, project, globalContext, sdk,
|
||||
AnalyzerFacadeProvider.getAnalyzerFacade(platform),
|
||||
platform,
|
||||
syntheticFiles, delegateResolverForProject, moduleFilter,
|
||||
allModules,
|
||||
builtIns,
|
||||
delegateResolverProvider?.builtInsCache,
|
||||
dependencies
|
||||
)
|
||||
|
||||
if (newBuiltIns is JvmBuiltIns) {
|
||||
val sdkInfo = SdkInfo(project, sdk!!)
|
||||
newBuiltIns.initialize(
|
||||
moduleResolverProvider.resolverForProject.descriptorForModule(sdkInfo),
|
||||
moduleResolverProvider.resolverForProject.resolverForModule(sdkInfo)
|
||||
.componentProvider.get<LanguageVersionSettings>()
|
||||
.supportsFeature(LanguageFeature.AdditionalBuiltInsMembers))
|
||||
}
|
||||
|
||||
moduleResolverProvider
|
||||
}
|
||||
|
||||
+26
-12
@@ -23,19 +23,20 @@ import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.roots.JdkOrderEntry
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import org.jetbrains.kotlin.analyzer.AnalyzerFacade
|
||||
import org.jetbrains.kotlin.analyzer.ModuleContent
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ResolverForProject
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.context.GlobalContextImpl
|
||||
import org.jetbrains.kotlin.context.withProject
|
||||
import org.jetbrains.kotlin.descriptors.SourceKind
|
||||
import org.jetbrains.kotlin.idea.project.AnalyzerFacadeProvider
|
||||
import org.jetbrains.kotlin.idea.project.IdeaEnvironment
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
|
||||
|
||||
fun createModuleResolverProvider(
|
||||
@@ -43,14 +44,21 @@ fun createModuleResolverProvider(
|
||||
project: Project,
|
||||
globalContext: GlobalContextImpl,
|
||||
sdk: Sdk?,
|
||||
analyzerFacade: AnalyzerFacade<JvmPlatformParameters>,
|
||||
platform: TargetPlatform,
|
||||
syntheticFiles: Collection<KtFile>,
|
||||
delegateResolver: ResolverForProject<IdeaModuleInfo>,
|
||||
moduleFilter: (IdeaModuleInfo) -> Boolean,
|
||||
allModules: Collection<IdeaModuleInfo>?,
|
||||
builtIns: KotlinBuiltIns,
|
||||
builtInsCache: BuiltInsCache?, // this cache is null only for SDK resolver provider
|
||||
dependencies: Collection<Any>
|
||||
): ModuleResolverProvider {
|
||||
var sdkBuiltIns: KotlinBuiltIns? = null
|
||||
|
||||
val builtInsProvider: (ModuleInfo) -> KotlinBuiltIns = builtInsCache?.let { it::getBuiltIns } ?: run {
|
||||
sdkBuiltIns = BuiltInsCache.calculateBuiltIns(platform, sdk, globalContext);
|
||||
|
||||
{ _: ModuleInfo -> sdkBuiltIns!! }
|
||||
}
|
||||
|
||||
val allModuleInfos = (allModules ?: collectAllModuleInfosFromIdeaModel(project)).toHashSet()
|
||||
|
||||
@@ -71,10 +79,10 @@ fun createModuleResolverProvider(
|
||||
psiClass.getNullableModuleInfo()
|
||||
}
|
||||
|
||||
val resolverForProject = analyzerFacade.setupResolverForProject(
|
||||
return AnalyzerFacadeProvider.getAnalyzerFacade(platform).setupResolverForProject(
|
||||
debugName, globalContext.withProject(project), modulesToCreateResolversFor, modulesContent,
|
||||
jvmPlatformParameters, IdeaEnvironment, builtIns,
|
||||
delegateResolver, { m, c -> IDEPackagePartProvider(c.moduleContentScope) },
|
||||
jvmPlatformParameters, IdeaEnvironment, builtInsProvider,
|
||||
delegateResolver, { _, c -> IDEPackagePartProvider(c.moduleContentScope) },
|
||||
sdk?.let { SdkInfo(project, it) },
|
||||
modulePlatforms = { moduleInfo ->
|
||||
val module = (moduleInfo as? ModuleSourceInfo)?.module
|
||||
@@ -89,14 +97,19 @@ fun createModuleResolverProvider(
|
||||
}
|
||||
|
||||
)
|
||||
return resolverForProject
|
||||
}
|
||||
|
||||
val resolverForProject = createResolverForProject()
|
||||
|
||||
val newBuiltInsCache = builtInsCache ?: run {
|
||||
val sdkModuleDescriptor = sdk?.let { resolverForProject.descriptorForModule(SdkInfo(project, it)) }
|
||||
|
||||
BuiltInsCache.createCacheAndInitializeBuiltIns(project, platform, sdk, sdkModuleDescriptor, sdkBuiltIns!!, globalContext)
|
||||
}
|
||||
|
||||
return ModuleResolverProviderImpl(
|
||||
resolverForProject,
|
||||
builtIns,
|
||||
newBuiltInsCache,
|
||||
dependencies + listOf(globalContext.exceptionTracker)
|
||||
)
|
||||
}
|
||||
@@ -133,11 +146,12 @@ fun getAllProjectSdks(): Collection<Sdk> {
|
||||
|
||||
interface ModuleResolverProvider {
|
||||
val resolverForProject: ResolverForProject<IdeaModuleInfo>
|
||||
val builtIns: KotlinBuiltIns
|
||||
val builtInsCache: BuiltInsCache
|
||||
val cacheDependencies: Collection<Any>
|
||||
}
|
||||
|
||||
class ModuleResolverProviderImpl(
|
||||
override val resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
||||
override val builtIns: KotlinBuiltIns,
|
||||
override val cacheDependencies: Collection<Any>) : ModuleResolverProvider
|
||||
override val builtInsCache: BuiltInsCache,
|
||||
override val cacheDependencies: Collection<Any>
|
||||
) : ModuleResolverProvider
|
||||
|
||||
Reference in New Issue
Block a user