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:
Stanislav Erokhin
2017-01-28 06:05:58 +03:00
committed by Dmitry Jemerov
parent 7c0cdf90cf
commit e38ca44595
6 changed files with 122 additions and 47 deletions
@@ -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)
@@ -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
}
}
}
@@ -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
}
@@ -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