Introduce AbstractResolverForProject
Previously, ResolverForProjectImpl had multiple callbacks in constructor. Some of those callbacks were used only to overcome module visibility and provide an ability to inject IDE-specific logic into compiler (ResolverForProject is in the 'compiler'-module) This commit introduces abstract class which implements environment-independent logic (previously, this logic had been stored in ResolverForProjectImpl) with several abstract met hods (previously, callbacks). Then, we provide few concrete implementations of AbstractResolverForProject with clear semantics: - IdeaResolverForProject: resolver used in IDE, where we have indices, oracles, multiple modules, etc. - ResolverForSingleModuleProject: resolver for project with only one module, commonly used for CLI compiler/tests - one anonymous implementation for MultimoduleTests This refactoring achieves several things: - now it is easier to see what kinds of ResolverForProject you might see in some particular environment (previously, one had to inspect all call-sites of constructor) - we can easily add IDE-specific logic in IdeaResolverForProject without adding noisy callbacks (which most probably wouldn't have any other non-trivial implementations)
This commit is contained in:
+13
-26
@@ -124,35 +124,22 @@ class CommonResolverForModuleFactory(
|
|||||||
else languageVersionSettings.getFeatureSupport(feature)
|
else languageVersionSettings.getFeatureSupport(feature)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val resolverForModuleFactory = CommonResolverForModuleFactory(
|
||||||
|
CommonAnalysisParameters(metadataPartProviderFactory),
|
||||||
|
CompilerEnvironment,
|
||||||
|
CommonPlatforms.defaultCommonPlatform,
|
||||||
|
shouldCheckExpectActual = false
|
||||||
|
)
|
||||||
|
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
val resolver = ResolverForProjectImpl(
|
val resolver = ResolverForSingleModuleProject(
|
||||||
"sources for metadata serializer",
|
"sources for metadata serializer",
|
||||||
ProjectContext(project, "metadata serializer"),
|
ProjectContext(project, "metadata serializer"),
|
||||||
listOf(moduleInfo),
|
moduleInfo,
|
||||||
invalidateOnOOCB = false,
|
resolverForModuleFactory,
|
||||||
modulesContent = { ModuleContent(it, files, GlobalSearchScope.allScope(project)) },
|
GlobalSearchScope.allScope(project),
|
||||||
moduleLanguageSettingsProvider = object : LanguageSettingsProvider {
|
languageVersionSettings = multiplatformLanguageSettings,
|
||||||
override fun getLanguageVersionSettings(
|
syntheticFiles = files
|
||||||
moduleInfo: ModuleInfo,
|
|
||||||
project: Project,
|
|
||||||
isReleaseCoroutines: Boolean?
|
|
||||||
) = multiplatformLanguageSettings
|
|
||||||
|
|
||||||
override fun getTargetPlatform(
|
|
||||||
moduleInfo: ModuleInfo,
|
|
||||||
project: Project
|
|
||||||
) = TargetPlatformVersion.NoVersion
|
|
||||||
},
|
|
||||||
resolverForModuleFactoryByPlatform = {
|
|
||||||
CommonResolverForModuleFactory(
|
|
||||||
CommonAnalysisParameters(metadataPartProviderFactory),
|
|
||||||
CompilerEnvironment,
|
|
||||||
CommonPlatforms.defaultCommonPlatform,
|
|
||||||
shouldCheckExpectActual = false
|
|
||||||
)
|
|
||||||
},
|
|
||||||
builtInsProvider = { DefaultBuiltIns.Instance },
|
|
||||||
sdkDependency = { null }
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val moduleDescriptor = resolver.descriptorForModule(moduleInfo)
|
val moduleDescriptor = resolver.descriptorForModule(moduleInfo)
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ abstract class ResolverForProject<M : ModuleInfo> {
|
|||||||
|
|
||||||
abstract val name: String
|
abstract val name: String
|
||||||
abstract val allModules: Collection<M>
|
abstract val allModules: Collection<M>
|
||||||
abstract val builtInsProvider: (M) -> KotlinBuiltIns
|
|
||||||
|
|
||||||
override fun toString() = name
|
override fun toString() = name
|
||||||
|
|
||||||
@@ -79,7 +78,6 @@ class EmptyResolverForProject<M : ModuleInfo> : ResolverForProject<M>() {
|
|||||||
override fun descriptorForModule(moduleInfo: M) = diagnoseUnknownModuleInfo(listOf(moduleInfo))
|
override fun descriptorForModule(moduleInfo: M) = diagnoseUnknownModuleInfo(listOf(moduleInfo))
|
||||||
override val allModules: Collection<M> = listOf()
|
override val allModules: Collection<M> = listOf()
|
||||||
override fun diagnoseUnknownModuleInfo(infos: List<ModuleInfo>) = throw IllegalStateException("Should not be called for $infos")
|
override fun diagnoseUnknownModuleInfo(infos: List<ModuleInfo>) = throw IllegalStateException("Should not be called for $infos")
|
||||||
override val builtInsProvider: (M) -> KotlinBuiltIns = { DefaultBuiltIns.Instance }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ModuleContent<out M : ModuleInfo>(
|
data class ModuleContent<out M : ModuleInfo>(
|
||||||
@@ -128,7 +126,7 @@ class LazyModuleDependencies<M : ModuleInfo>(
|
|||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
private val module: M,
|
private val module: M,
|
||||||
firstDependency: M? = null,
|
firstDependency: M? = null,
|
||||||
private val resolverForProject: ResolverForProjectImpl<M>
|
private val resolverForProject: AbstractResolverForProject<M>
|
||||||
) : ModuleDependencies {
|
) : ModuleDependencies {
|
||||||
private val dependencies = storageManager.createLazyValue {
|
private val dependencies = storageManager.createLazyValue {
|
||||||
val moduleDescriptor = resolverForProject.descriptorForModule(module)
|
val moduleDescriptor = resolverForProject.descriptorForModule(module)
|
||||||
|
|||||||
@@ -16,20 +16,15 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
class ResolverForProjectImpl<M : ModuleInfo>(
|
abstract class AbstractResolverForProject<M : ModuleInfo>(
|
||||||
private val debugName: String,
|
private val debugName: String,
|
||||||
private val projectContext: ProjectContext,
|
protected val projectContext: ProjectContext,
|
||||||
modules: Collection<M>,
|
modules: Collection<M>,
|
||||||
private val modulesContent: (M) -> ModuleContent<M>,
|
private val fallbackModificationTracker: ModificationTracker? = null,
|
||||||
private val moduleLanguageSettingsProvider: LanguageSettingsProvider,
|
|
||||||
private val resolverForModuleFactoryByPlatform: (TargetPlatform?) -> ResolverForModuleFactory,
|
|
||||||
private val invalidateOnOOCB: Boolean,
|
|
||||||
override val builtInsProvider: (M) -> KotlinBuiltIns,
|
|
||||||
private val delegateResolver: ResolverForProject<M> = EmptyResolverForProject(),
|
private val delegateResolver: ResolverForProject<M> = EmptyResolverForProject(),
|
||||||
private val sdkDependency: (M) -> M?,
|
private val packageOracleFactory: PackageOracleFactory = PackageOracleFactory.OptimisticFactory
|
||||||
private val packageOracleFactory: PackageOracleFactory = PackageOracleFactory.OptimisticFactory,
|
|
||||||
private val isReleaseCoroutines: Boolean? = null
|
|
||||||
) : ResolverForProject<M>() {
|
) : ResolverForProject<M>() {
|
||||||
|
|
||||||
private class ModuleData(
|
private class ModuleData(
|
||||||
@@ -58,6 +53,11 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
|||||||
assert(moduleInfoToResolvableInfo.values.toSet() == modules.toSet())
|
assert(moduleInfoToResolvableInfo.values.toSet() == modules.toSet())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract fun sdkDependency(module: M): M?
|
||||||
|
abstract fun modulesContent(module: M): ModuleContent<M>
|
||||||
|
abstract fun builtInsForModule(module: M): KotlinBuiltIns
|
||||||
|
abstract fun createResolverForModule(descriptor: ModuleDescriptor, moduleInfo: M): ResolverForModule
|
||||||
|
|
||||||
override fun tryGetResolverForModule(moduleInfo: M): ResolverForModule? {
|
override fun tryGetResolverForModule(moduleInfo: M): ResolverForModule? {
|
||||||
if (!isCorrectModuleInfo(moduleInfo)) {
|
if (!isCorrectModuleInfo(moduleInfo)) {
|
||||||
return null
|
return null
|
||||||
@@ -108,25 +108,9 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
|||||||
resolverByModuleDescriptor.getOrPut(descriptor) {
|
resolverByModuleDescriptor.getOrPut(descriptor) {
|
||||||
checkModuleIsCorrect(module)
|
checkModuleIsCorrect(module)
|
||||||
|
|
||||||
ResolverForModuleComputationTracker.getInstance(projectContext.project)
|
ResolverForModuleComputationTracker.getInstance(projectContext.project)?.onResolverComputed(module)
|
||||||
?.onResolverComputed(module)
|
|
||||||
|
|
||||||
val moduleContent = modulesContent(module)
|
createResolverForModule(descriptor, module)
|
||||||
|
|
||||||
val languageVersionSettings =
|
|
||||||
moduleLanguageSettingsProvider.getLanguageVersionSettings(module, projectContext.project, isReleaseCoroutines)
|
|
||||||
|
|
||||||
// FIXME(dsavvinov): make sure that module.platform returns platform with the same JvmTarget as this one
|
|
||||||
val targetPlatformVersion = moduleLanguageSettingsProvider.getTargetPlatform(module, projectContext.project)
|
|
||||||
|
|
||||||
val resolverForModuleFactory = resolverForModuleFactoryByPlatform(module.platform)
|
|
||||||
resolverForModuleFactory.createResolverForModule(
|
|
||||||
descriptor as ModuleDescriptorImpl,
|
|
||||||
projectContext.withModule(descriptor),
|
|
||||||
moduleContent,
|
|
||||||
this@ResolverForProjectImpl,
|
|
||||||
languageVersionSettings
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +137,7 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
|||||||
|
|
||||||
private fun doGetDescriptorForModule(module: M): ModuleDescriptorImpl {
|
private fun doGetDescriptorForModule(module: M): ModuleDescriptorImpl {
|
||||||
val moduleFromThisResolver = moduleInfoToResolvableInfo[module]
|
val moduleFromThisResolver = moduleInfoToResolvableInfo[module]
|
||||||
?: return delegateResolver.descriptorForModule(module) as ModuleDescriptorImpl
|
?: return delegateResolver.descriptorForModule(module) as ModuleDescriptorImpl
|
||||||
|
|
||||||
return projectContext.storageManager.compute {
|
return projectContext.storageManager.compute {
|
||||||
var moduleData = descriptorByModule.getOrPut(moduleFromThisResolver) {
|
var moduleData = descriptorByModule.getOrPut(moduleFromThisResolver) {
|
||||||
@@ -183,24 +167,20 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
|||||||
val moduleDescriptor = ModuleDescriptorImpl(
|
val moduleDescriptor = ModuleDescriptorImpl(
|
||||||
module.name,
|
module.name,
|
||||||
projectContext.storageManager,
|
projectContext.storageManager,
|
||||||
builtInsProvider(module),
|
builtInsForModule(module),
|
||||||
module.platform,
|
module.platform,
|
||||||
module.capabilities,
|
module.capabilities,
|
||||||
module.stableName
|
module.stableName
|
||||||
)
|
)
|
||||||
moduleInfoByDescriptor[moduleDescriptor] = module
|
moduleInfoByDescriptor[moduleDescriptor] = module
|
||||||
setupModuleDescriptor(module, moduleDescriptor)
|
setupModuleDescriptor(module, moduleDescriptor)
|
||||||
val modificationTracker = (module as? TrackableModuleInfo)?.createModificationTracker() ?: if (invalidateOnOOCB) {
|
val modificationTracker = (module as? TrackableModuleInfo)?.createModificationTracker() ?: fallbackModificationTracker
|
||||||
KotlinModificationTrackerService.getInstance(projectContext.project).outOfBlockModificationTracker
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
return ModuleData(moduleDescriptor, modificationTracker)
|
return ModuleData(moduleDescriptor, modificationTracker)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DelegatingPackageFragmentProvider<M : ModuleInfo>(
|
private class DelegatingPackageFragmentProvider<M : ModuleInfo>(
|
||||||
private val resolverForProject: ResolverForProjectImpl<M>,
|
private val resolverForProject: AbstractResolverForProject<M>,
|
||||||
private val module: ModuleDescriptor,
|
private val module: ModuleDescriptor,
|
||||||
moduleContent: ModuleContent<M>,
|
moduleContent: ModuleContent<M>,
|
||||||
private val packageOracle: PackageOracle
|
private val packageOracle: PackageOracle
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.analyzer
|
||||||
|
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||||
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
|
import org.jetbrains.kotlin.context.withModule
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
|
class ResolverForSingleModuleProject<M : ModuleInfo>(
|
||||||
|
debugName: String,
|
||||||
|
projectContext: ProjectContext,
|
||||||
|
module: M,
|
||||||
|
private val resolverForModuleFactory: ResolverForModuleFactory,
|
||||||
|
private val searchScope: GlobalSearchScope,
|
||||||
|
private val builtIns: KotlinBuiltIns = DefaultBuiltIns.Instance,
|
||||||
|
private val languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||||
|
private val syntheticFiles: Collection<KtFile> = emptyList(),
|
||||||
|
private val sdkDependency: M? = null
|
||||||
|
) : AbstractResolverForProject<M>(
|
||||||
|
debugName,
|
||||||
|
projectContext,
|
||||||
|
listOf(module),
|
||||||
|
null,
|
||||||
|
EmptyResolverForProject(),
|
||||||
|
PackageOracleFactory.OptimisticFactory
|
||||||
|
) {
|
||||||
|
override fun sdkDependency(module: M): M? = sdkDependency
|
||||||
|
|
||||||
|
override fun modulesContent(module: M): ModuleContent<M> = ModuleContent(module, syntheticFiles, searchScope)
|
||||||
|
|
||||||
|
override fun builtInsForModule(module: M): KotlinBuiltIns = builtIns
|
||||||
|
|
||||||
|
override fun createResolverForModule(descriptor: ModuleDescriptor, moduleInfo: M): ResolverForModule =
|
||||||
|
resolverForModuleFactory.createResolverForModule(
|
||||||
|
descriptor as ModuleDescriptorImpl,
|
||||||
|
projectContext.withModule(descriptor),
|
||||||
|
modulesContent(moduleInfo),
|
||||||
|
this,
|
||||||
|
languageVersionSettings
|
||||||
|
)
|
||||||
|
}
|
||||||
+8
-10
@@ -46,18 +46,16 @@ fun createResolveSessionForFiles(
|
|||||||
packagePartProviderFactory = { PackagePartProvider.Empty },
|
packagePartProviderFactory = { PackagePartProvider.Empty },
|
||||||
moduleByJavaClass = { testModule }
|
moduleByJavaClass = { testModule }
|
||||||
)
|
)
|
||||||
val resolverForProject = ResolverForProjectImpl(
|
|
||||||
|
val resolverForProject = ResolverForSingleModuleProject(
|
||||||
"test",
|
"test",
|
||||||
projectContext, listOf(testModule),
|
projectContext,
|
||||||
{ ModuleContent(it, syntheticFiles, GlobalSearchScope.allScope(project)) },
|
testModule,
|
||||||
invalidateOnOOCB = false,
|
JvmResolverForModuleFactory(platformParameters, CompilerEnvironment, JvmPlatforms.defaultJvmPlatform),
|
||||||
moduleLanguageSettingsProvider = LanguageSettingsProvider.Default,
|
GlobalSearchScope.allScope(project),
|
||||||
resolverForModuleFactoryByPlatform = {
|
syntheticFiles = syntheticFiles
|
||||||
JvmResolverForModuleFactory(platformParameters, CompilerEnvironment, JvmPlatforms.defaultJvmPlatform)
|
|
||||||
},
|
|
||||||
builtInsProvider = { DefaultBuiltIns.Instance },
|
|
||||||
sdkDependency = { null }
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return resolverForProject.resolverForModule(testModule).componentProvider.get<ResolveSession>()
|
return resolverForProject.resolverForModule(testModule).componentProvider.get<ResolveSession>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+33
-15
@@ -28,9 +28,12 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
|||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||||
import org.jetbrains.kotlin.container.get
|
import org.jetbrains.kotlin.container.get
|
||||||
import org.jetbrains.kotlin.context.ProjectContext
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
|
import org.jetbrains.kotlin.context.withModule
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -87,24 +90,39 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() {
|
|||||||
modules.first { it._name == moduleName }
|
modules.first { it._name == moduleName }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
val resolverForProject = ResolverForProjectImpl(
|
|
||||||
|
val resolverForProject = object : AbstractResolverForProject<TestModule>(
|
||||||
"test",
|
"test",
|
||||||
projectContext, modules,
|
projectContext,
|
||||||
invalidateOnOOCB = false,
|
modules
|
||||||
modulesContent = { module -> ModuleContent(module, module.kotlinFiles, module.javaFilesScope) },
|
) {
|
||||||
moduleLanguageSettingsProvider = LanguageSettingsProvider.Default,
|
override fun sdkDependency(module: TestModule): TestModule? = null
|
||||||
resolverForModuleFactoryByPlatform = {
|
|
||||||
JvmResolverForModuleFactory(platformParameters, CompilerEnvironment, JvmPlatforms.defaultJvmPlatform)
|
override fun modulesContent(module: TestModule): ModuleContent<TestModule> =
|
||||||
},
|
ModuleContent(module, module.kotlinFiles, module.javaFilesScope)
|
||||||
sdkDependency = { null },
|
|
||||||
builtInsProvider = { builtIns }
|
override fun builtInsForModule(module: TestModule): KotlinBuiltIns = builtIns
|
||||||
)
|
|
||||||
|
override fun createResolverForModule(descriptor: ModuleDescriptor, moduleInfo: TestModule): ResolverForModule =
|
||||||
|
JvmResolverForModuleFactory(
|
||||||
|
platformParameters,
|
||||||
|
CompilerEnvironment,
|
||||||
|
JvmPlatforms.defaultJvmPlatform
|
||||||
|
).createResolverForModule(
|
||||||
|
descriptor as ModuleDescriptorImpl,
|
||||||
|
projectContext.withModule(descriptor),
|
||||||
|
modulesContent(moduleInfo),
|
||||||
|
this,
|
||||||
|
LanguageVersionSettingsImpl.DEFAULT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
builtIns.initialize(
|
builtIns.initialize(
|
||||||
resolverForProject.descriptorForModule(resolverForProject.allModules.first()),
|
resolverForProject.descriptorForModule(resolverForProject.allModules.first()),
|
||||||
resolverForProject.resolverForModule(resolverForProject.allModules.first())
|
resolverForProject.resolverForModule(resolverForProject.allModules.first())
|
||||||
.componentProvider.get<LanguageVersionSettings>()
|
.componentProvider.get<LanguageVersionSettings>()
|
||||||
.supportsFeature(LanguageFeature.AdditionalBuiltInsMembers))
|
.supportsFeature(LanguageFeature.AdditionalBuiltInsMembers)
|
||||||
|
)
|
||||||
|
|
||||||
performChecks(resolverForProject, modules)
|
performChecks(resolverForProject, modules)
|
||||||
}
|
}
|
||||||
|
|||||||
+124
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 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.caches.resolve
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.util.ModificationTracker
|
||||||
|
import org.jetbrains.kotlin.analyzer.*
|
||||||
|
import org.jetbrains.kotlin.analyzer.common.CommonAnalysisParameters
|
||||||
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
|
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.resolution
|
||||||
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
|
import org.jetbrains.kotlin.context.withModule
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
|
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.getPlatformModuleInfo
|
||||||
|
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
||||||
|
import org.jetbrains.kotlin.idea.project.IdeaEnvironment
|
||||||
|
import org.jetbrains.kotlin.idea.project.findAnalyzerServices
|
||||||
|
import org.jetbrains.kotlin.idea.project.useCompositeAnalysis
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||||
|
import org.jetbrains.kotlin.platform.idePlatformKind
|
||||||
|
import org.jetbrains.kotlin.platform.isCommon
|
||||||
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||||
|
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||||
|
import org.jetbrains.kotlin.platform.toTargetPlatform
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
|
||||||
|
|
||||||
|
class IdeaResolverForProject(
|
||||||
|
debugName: String,
|
||||||
|
projectContext: ProjectContext,
|
||||||
|
private val modules: Collection<IdeaModuleInfo>,
|
||||||
|
private val syntheticFilesByModule: Map<IdeaModuleInfo, Collection<KtFile>>,
|
||||||
|
delegateResolver: ResolverForProject<IdeaModuleInfo>,
|
||||||
|
private val builtInsCache: BuiltInsCache,
|
||||||
|
fallbackModificationTracker: ModificationTracker? = null,
|
||||||
|
private val isReleaseCoroutines: Boolean? = null,
|
||||||
|
// TODO(dsavvinov): this is needed only for non-composite analysis, extract separate resolver implementation instead
|
||||||
|
private val constantSdkDependencyIfAny: IdeaModuleInfo? = null
|
||||||
|
) : AbstractResolverForProject<IdeaModuleInfo>(
|
||||||
|
debugName,
|
||||||
|
projectContext,
|
||||||
|
modules,
|
||||||
|
fallbackModificationTracker,
|
||||||
|
delegateResolver,
|
||||||
|
ServiceManager.getService(projectContext.project, IdePackageOracleFactory::class.java)
|
||||||
|
) {
|
||||||
|
override fun sdkDependency(module: IdeaModuleInfo): IdeaModuleInfo? {
|
||||||
|
if (projectContext.project.useCompositeAnalysis) {
|
||||||
|
require(constantSdkDependencyIfAny == null) { "Shouldn't pass SDK dependency manually for composite analysis mode" }
|
||||||
|
}
|
||||||
|
return constantSdkDependencyIfAny ?: module.findSdkAcrossDependencies()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun modulesContent(module: IdeaModuleInfo): ModuleContent<IdeaModuleInfo> =
|
||||||
|
ModuleContent(module, syntheticFilesByModule[module] ?: emptyList(), module.contentScope())
|
||||||
|
|
||||||
|
override fun builtInsForModule(module: IdeaModuleInfo): KotlinBuiltIns {
|
||||||
|
require(module in modules)
|
||||||
|
val key = module.platform.idePlatformKind.resolution.getKeyForBuiltIns(module)
|
||||||
|
return builtInsCache.getOrPut(key) { throw IllegalStateException("Can't find builtIns by key $key for module $module") }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createResolverForModule(descriptor: ModuleDescriptor, moduleInfo: IdeaModuleInfo): ResolverForModule {
|
||||||
|
val moduleContent = ModuleContent(moduleInfo, syntheticFilesByModule[moduleInfo] ?: listOf(), moduleInfo.contentScope())
|
||||||
|
|
||||||
|
val languageVersionSettings =
|
||||||
|
IDELanguageSettingsProvider.getLanguageVersionSettings(moduleInfo, projectContext.project, isReleaseCoroutines)
|
||||||
|
|
||||||
|
val resolverForModuleFactory = getResolverForModuleFactory(moduleInfo)
|
||||||
|
|
||||||
|
return resolverForModuleFactory.createResolverForModule(
|
||||||
|
descriptor as ModuleDescriptorImpl,
|
||||||
|
projectContext.withModule(descriptor),
|
||||||
|
moduleContent,
|
||||||
|
this,
|
||||||
|
languageVersionSettings
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getResolverForModuleFactory(moduleInfo: IdeaModuleInfo): ResolverForModuleFactory {
|
||||||
|
val platform = moduleInfo.platform
|
||||||
|
|
||||||
|
val jvmPlatformParameters = JvmPlatformParameters(
|
||||||
|
packagePartProviderFactory = { IDEPackagePartProvider(it.moduleContentScope) },
|
||||||
|
moduleByJavaClass = { javaClass: JavaClass ->
|
||||||
|
val psiClass = (javaClass as JavaClassImpl).psi
|
||||||
|
psiClass.getPlatformModuleInfo(JvmPlatforms.unspecifiedJvmPlatform)?.platformModule ?: psiClass.getNullableModuleInfo()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
val commonPlatformParameters = CommonAnalysisParameters(
|
||||||
|
metadataPartProviderFactory = { IDEPackagePartProvider(it.moduleContentScope) }
|
||||||
|
)
|
||||||
|
|
||||||
|
return if (!projectContext.project.useCompositeAnalysis) {
|
||||||
|
val parameters = when {
|
||||||
|
platform.isJvm() -> jvmPlatformParameters
|
||||||
|
platform.isCommon() -> commonPlatformParameters
|
||||||
|
else -> PlatformAnalysisParameters.Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
platform.idePlatformKind.resolution.createResolverForModuleFactory(parameters, IdeaEnvironment, platform)
|
||||||
|
} else {
|
||||||
|
CompositeResolverForModuleFactory(
|
||||||
|
commonPlatformParameters,
|
||||||
|
jvmPlatformParameters,
|
||||||
|
platform,
|
||||||
|
CompositeAnalyzerServices(platform.componentPlatforms.map { it.toTargetPlatform().findAnalyzerServices })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-72
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.caches.resolve
|
package org.jetbrains.kotlin.idea.caches.resolve
|
||||||
|
|
||||||
import com.intellij.openapi.components.ServiceManager
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
import com.intellij.psi.util.CachedValueProvider
|
||||||
@@ -24,36 +23,18 @@ import com.intellij.psi.util.CachedValuesManager
|
|||||||
import com.intellij.psi.util.PsiModificationTracker
|
import com.intellij.psi.util.PsiModificationTracker
|
||||||
import com.intellij.util.containers.SLRUCache
|
import com.intellij.util.containers.SLRUCache
|
||||||
import org.jetbrains.kotlin.analyzer.*
|
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.builtins.jvm.JvmBuiltIns
|
||||||
import org.jetbrains.kotlin.caches.resolve.CompositeAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.caches.resolve.CompositeResolverForModuleFactory
|
|
||||||
import org.jetbrains.kotlin.caches.resolve.resolution
|
import org.jetbrains.kotlin.caches.resolve.resolution
|
||||||
import org.jetbrains.kotlin.context.GlobalContextImpl
|
import org.jetbrains.kotlin.context.GlobalContextImpl
|
||||||
import org.jetbrains.kotlin.context.ProjectContext
|
|
||||||
import org.jetbrains.kotlin.context.withProject
|
import org.jetbrains.kotlin.context.withProject
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.project.*
|
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.getNullableModuleInfo
|
|
||||||
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
|
||||||
import org.jetbrains.kotlin.idea.project.IdeaEnvironment
|
|
||||||
import org.jetbrains.kotlin.idea.project.findAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.idea.project.useCompositeAnalysis
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
|
||||||
import org.jetbrains.kotlin.platform.idePlatformKind
|
import org.jetbrains.kotlin.platform.idePlatformKind
|
||||||
import org.jetbrains.kotlin.platform.isCommon
|
|
||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
|
||||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.CompositeBindingContext
|
import org.jetbrains.kotlin.resolve.CompositeBindingContext
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
import org.jetbrains.kotlin.platform.DefaultIdeTargetPlatformKindProvider
|
|
||||||
import org.jetbrains.kotlin.platform.toTargetPlatform
|
|
||||||
|
|
||||||
internal class ProjectResolutionFacade(
|
internal class ProjectResolutionFacade(
|
||||||
private val debugString: String,
|
private val debugString: String,
|
||||||
@@ -101,7 +82,6 @@ internal class ProjectResolutionFacade(
|
|||||||
|
|
||||||
private fun computeModuleResolverProvider(): ResolverForProject<IdeaModuleInfo> {
|
private fun computeModuleResolverProvider(): ResolverForProject<IdeaModuleInfo> {
|
||||||
val delegateResolverForProject: ResolverForProject<IdeaModuleInfo>
|
val delegateResolverForProject: ResolverForProject<IdeaModuleInfo>
|
||||||
val delegateBuiltIns: KotlinBuiltIns?
|
|
||||||
|
|
||||||
if (reuseDataFrom != null) {
|
if (reuseDataFrom != null) {
|
||||||
delegateResolverForProject = reuseDataFrom.cachedResolverForProject
|
delegateResolverForProject = reuseDataFrom.cachedResolverForProject
|
||||||
@@ -119,61 +99,16 @@ internal class ProjectResolutionFacade(
|
|||||||
|
|
||||||
val modulesToCreateResolversFor = allModuleInfos.filter(moduleFilter)
|
val modulesToCreateResolversFor = allModuleInfos.filter(moduleFilter)
|
||||||
|
|
||||||
val modulesContentFactory = { module: IdeaModuleInfo ->
|
val resolverForProject = IdeaResolverForProject(
|
||||||
ModuleContent(module, syntheticFilesByModule[module] ?: listOf(), module.contentScope())
|
|
||||||
}
|
|
||||||
|
|
||||||
val jvmPlatformParameters = JvmPlatformParameters(
|
|
||||||
packagePartProviderFactory = { IDEPackagePartProvider(it.moduleContentScope) },
|
|
||||||
moduleByJavaClass = { javaClass: JavaClass ->
|
|
||||||
val psiClass = (javaClass as JavaClassImpl).psi
|
|
||||||
psiClass.getPlatformModuleInfo(JvmPlatforms.unspecifiedJvmPlatform)?.platformModule ?: psiClass.getNullableModuleInfo()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
val commonPlatformParameters = CommonAnalysisParameters(
|
|
||||||
metadataPartProviderFactory = { IDEPackagePartProvider(it.moduleContentScope) }
|
|
||||||
)
|
|
||||||
|
|
||||||
val resolverForProject = ResolverForProjectImpl(
|
|
||||||
resolverDebugName,
|
resolverDebugName,
|
||||||
projectContext,
|
projectContext,
|
||||||
modulesToCreateResolversFor,
|
modulesToCreateResolversFor,
|
||||||
modulesContentFactory,
|
syntheticFilesByModule,
|
||||||
moduleLanguageSettingsProvider = IDELanguageSettingsProvider,
|
delegateResolverForProject,
|
||||||
resolverForModuleFactoryByPlatform = { modulePlatform ->
|
builtInsCache,
|
||||||
val platform = modulePlatform ?: DefaultIdeTargetPlatformKindProvider.defaultPlatform
|
if (invalidateOnOOCB) KotlinModificationTrackerService.getInstance(project).outOfBlockModificationTracker else null,
|
||||||
val parameters = when {
|
settings.isReleaseCoroutines,
|
||||||
platform.isJvm() -> jvmPlatformParameters
|
constantSdkDependencyIfAny = if (settings is PlatformAnalysisSettingsImpl) settings.sdk?.let { SdkInfo(project, it) } else null
|
||||||
platform.isCommon() -> commonPlatformParameters
|
|
||||||
else -> PlatformAnalysisParameters.Empty
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!project.useCompositeAnalysis)
|
|
||||||
platform.idePlatformKind.resolution.createResolverForModuleFactory(parameters, IdeaEnvironment, platform)
|
|
||||||
else
|
|
||||||
CompositeResolverForModuleFactory(
|
|
||||||
commonPlatformParameters,
|
|
||||||
jvmPlatformParameters,
|
|
||||||
modulePlatform!!,
|
|
||||||
CompositeAnalyzerServices(modulePlatform.componentPlatforms.map { it.toTargetPlatform().findAnalyzerServices })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
builtInsProvider = { module ->
|
|
||||||
require(module in modulesToCreateResolversFor)
|
|
||||||
val key = module.platform.idePlatformKind.resolution.getKeyForBuiltIns(module)
|
|
||||||
builtInsCache.getOrPut(key) { throw IllegalStateException("Can't find builtIns by key $key for module $module") }
|
|
||||||
},
|
|
||||||
delegateResolver = delegateResolverForProject,
|
|
||||||
sdkDependency = { module ->
|
|
||||||
if (settings is PlatformAnalysisSettingsImpl)
|
|
||||||
settings.sdk?.let { SdkInfo(project, it) }
|
|
||||||
else
|
|
||||||
module.findSdkAcrossDependencies()
|
|
||||||
},
|
|
||||||
packageOracleFactory = ServiceManager.getService(project, IdePackageOracleFactory::class.java),
|
|
||||||
invalidateOnOOCB = invalidateOnOOCB,
|
|
||||||
isReleaseCoroutines = settings.isReleaseCoroutines
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Fill builtInsCache
|
// Fill builtInsCache
|
||||||
|
|||||||
Reference in New Issue
Block a user