Refactoring: move createResolverForModule() into ResolverForProjectImpl
This commit is contained in:
@@ -43,13 +43,13 @@ class JvmPlatformParameters(
|
||||
) : PlatformAnalysisParameters
|
||||
|
||||
|
||||
object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
|
||||
object JvmAnalyzerFacade : AnalyzerFacade() {
|
||||
override fun <M : ModuleInfo> createResolverForModule(
|
||||
moduleInfo: M,
|
||||
moduleDescriptor: ModuleDescriptorImpl,
|
||||
moduleContext: ModuleContext,
|
||||
moduleContent: ModuleContent,
|
||||
platformParameters: JvmPlatformParameters,
|
||||
platformParameters: PlatformAnalysisParameters,
|
||||
targetEnvironment: TargetEnvironment,
|
||||
resolverForProject: ResolverForProject<M>,
|
||||
languageSettingsProvider: LanguageSettingsProvider,
|
||||
@@ -64,7 +64,7 @@ object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
|
||||
)
|
||||
|
||||
val moduleClassResolver = ModuleClassResolverImpl { javaClass ->
|
||||
val referencedClassModule = platformParameters.moduleByJavaClass(javaClass)
|
||||
val referencedClassModule = (platformParameters as JvmPlatformParameters).moduleByJavaClass(javaClass)
|
||||
// We don't have full control over idea resolve api so we allow for a situation which should not happen in Kotlin.
|
||||
// For example, type in a java library can reference a class declared in a source root (is valid but rare case)
|
||||
// Providing a fallback strategy in this case can hide future problems, so we should at least log to be able to diagnose those
|
||||
|
||||
@@ -75,6 +75,12 @@ class EmptyResolverForProject<M : ModuleInfo> : ResolverForProject<M>() {
|
||||
}
|
||||
|
||||
class ResolverForProjectImpl<M : ModuleInfo>(
|
||||
val projectContext: ProjectContext,
|
||||
analyzerFacade: (M) -> AnalyzerFacade,
|
||||
modulesContent: (M) -> ModuleContent,
|
||||
platformParameters: PlatformAnalysisParameters,
|
||||
targetEnvironment: TargetEnvironment,
|
||||
packagePartProviderFactory: (M, ModuleContent) -> PackagePartProvider,
|
||||
private val debugName: String,
|
||||
private val descriptorByModule: Map<M, ModuleDescriptorImpl>,
|
||||
private val delegateResolver: ResolverForProject<M> = EmptyResolverForProject()
|
||||
@@ -86,7 +92,17 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
||||
return resolverForModuleDescriptor(doGetDescriptorForModule(moduleInfo))
|
||||
}
|
||||
|
||||
internal val resolverByModuleDescriptor: MutableMap<ModuleDescriptor, NotNullLazyValue<ResolverForModule>> = HashMap()
|
||||
internal val resolverByModuleDescriptor: Map<ModuleDescriptor, NotNullLazyValue<ResolverForModule>> = descriptorByModule.map { (module, descriptor) ->
|
||||
descriptor to projectContext.storageManager.createLazyValue {
|
||||
ResolverForModuleComputationTracker.getInstance(projectContext.project)?.onResolverComputed(module)
|
||||
|
||||
analyzerFacade(module).createResolverForModule(
|
||||
module, descriptor, projectContext.withModule(descriptor), modulesContent(module),
|
||||
platformParameters, targetEnvironment, this@ResolverForProjectImpl,
|
||||
packagePartProviderFactory(module, modulesContent(module))
|
||||
)
|
||||
}
|
||||
}.toMap()
|
||||
|
||||
override val allModules: Collection<M> by lazy {
|
||||
(descriptorByModule.keys + delegateResolver.allModules).toSet()
|
||||
@@ -156,15 +172,15 @@ interface ModuleInfo {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
||||
abstract class AnalyzerFacade {
|
||||
companion object {
|
||||
fun <P : PlatformAnalysisParameters, M : ModuleInfo> setupResolverForProject(
|
||||
fun <M : ModuleInfo> setupResolverForProject(
|
||||
debugName: String,
|
||||
projectContext: ProjectContext,
|
||||
modules: Collection<M>,
|
||||
analyzerFacade: (M) -> AnalyzerFacade<P>,
|
||||
analyzerFacade: (M) -> AnalyzerFacade,
|
||||
modulesContent: (M) -> ModuleContent,
|
||||
platformParameters: P,
|
||||
platformParameters: PlatformAnalysisParameters,
|
||||
languageSettingsProvider: LanguageSettingsProvider = LanguageSettingsProvider.Default,
|
||||
targetEnvironment: TargetEnvironment = CompilerEnvironment,
|
||||
builtIns: KotlinBuiltIns = DefaultBuiltIns.Instance,
|
||||
@@ -176,9 +192,17 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
||||
): ResolverForProject<M> {
|
||||
val storageManager = projectContext.storageManager
|
||||
|
||||
val resolverForProject = ResolverForProjectImpl(debugName, modules.keysToMap { module ->
|
||||
ModuleDescriptorImpl(module.name, storageManager, builtIns, modulePlatforms(module), module.capabilities)
|
||||
}, delegateResolver)
|
||||
val resolverForProject = ResolverForProjectImpl(
|
||||
projectContext,
|
||||
analyzerFacade,
|
||||
modulesContent,
|
||||
platformParameters,
|
||||
targetEnvironment,
|
||||
packagePartProviderFactory,
|
||||
debugName,
|
||||
modules.keysToMap { module ->
|
||||
ModuleDescriptorImpl(module.name, storageManager, builtIns, modulePlatforms(module), module.capabilities)
|
||||
}, delegateResolver)
|
||||
|
||||
for (module in modules) {
|
||||
val moduleDescriptor = resolverForProject.descriptorForModule(module)
|
||||
@@ -188,37 +212,23 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
||||
modulePlatforms,
|
||||
firstDependency,
|
||||
resolverForProject))
|
||||
}
|
||||
|
||||
for (module in modules) {
|
||||
val descriptor = resolverForProject.descriptorForModule(module)
|
||||
val content = modulesContent(module)
|
||||
val computeResolverForModule = storageManager.createLazyValue {
|
||||
ResolverForModuleComputationTracker.getInstance(projectContext.project)?.onResolverComputed(module)
|
||||
|
||||
analyzerFacade(module).createResolverForModule(
|
||||
module, descriptor, projectContext.withModule(descriptor), modulesContent(module),
|
||||
platformParameters, targetEnvironment, resolverForProject, languageSettingsProvider,
|
||||
packagePartProviderFactory(module, content)
|
||||
)
|
||||
}
|
||||
|
||||
descriptor.initialize(
|
||||
DelegatingPackageFragmentProvider(content, packageOracleFactory.createOracle(module), computeResolverForModule))
|
||||
|
||||
resolverForProject.resolverByModuleDescriptor[descriptor] = computeResolverForModule
|
||||
moduleDescriptor.initialize(
|
||||
DelegatingPackageFragmentProvider(resolverForProject, moduleDescriptor, content,
|
||||
packageOracleFactory.createOracle(module)))
|
||||
}
|
||||
|
||||
return resolverForProject
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun <M : ModuleInfo> createResolverForModule(
|
||||
abstract fun <M : ModuleInfo> createResolverForModule(
|
||||
moduleInfo: M,
|
||||
moduleDescriptor: ModuleDescriptorImpl,
|
||||
moduleContext: ModuleContext,
|
||||
moduleContent: ModuleContent,
|
||||
platformParameters: P,
|
||||
platformParameters: PlatformAnalysisParameters,
|
||||
targetEnvironment: TargetEnvironment,
|
||||
resolverForProject: ResolverForProject<M>,
|
||||
languageSettingsProvider: LanguageSettingsProvider,
|
||||
@@ -272,27 +282,31 @@ class LazyModuleDependencies<M: ModuleInfo>(
|
||||
}
|
||||
|
||||
|
||||
private class DelegatingPackageFragmentProvider(
|
||||
private class DelegatingPackageFragmentProvider<M : ModuleInfo>(
|
||||
private val resolverForProject: ResolverForProjectImpl<M>,
|
||||
private val module: ModuleDescriptor,
|
||||
moduleContent: ModuleContent,
|
||||
private val packageOracle: PackageOracle,
|
||||
private val resolverForModule: NotNullLazyValue<ResolverForModule>
|
||||
private val packageOracle: PackageOracle
|
||||
) : PackageFragmentProvider {
|
||||
private val syntheticFilePackages = moduleContent.syntheticFiles.map { it.packageFqName }.toSet()
|
||||
|
||||
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> {
|
||||
if (certainlyDoesNotExist(fqName)) return emptyList()
|
||||
|
||||
return resolverForModule().packageFragmentProvider.getPackageFragments(fqName)
|
||||
return resolverForModuleCachedValue().packageFragmentProvider.getPackageFragments(fqName)
|
||||
}
|
||||
|
||||
private val resolverForModuleCachedValue
|
||||
get() = resolverForProject.resolverByModuleDescriptor[module]!!
|
||||
|
||||
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> {
|
||||
if (certainlyDoesNotExist(fqName)) return emptyList()
|
||||
|
||||
return resolverForModule().packageFragmentProvider.getSubPackagesOf(fqName, nameFilter)
|
||||
return resolverForModuleCachedValue().packageFragmentProvider.getSubPackagesOf(fqName, nameFilter)
|
||||
}
|
||||
|
||||
private fun certainlyDoesNotExist(fqName: FqName): Boolean {
|
||||
if (resolverForModule.isComputed()) return false // let this request get cached inside delegate
|
||||
if (resolverForModuleCachedValue.isComputed()) return false // let this request get cached inside delegate
|
||||
|
||||
return !packageOracle.packageExists(fqName) && fqName !in syntheticFilePackages
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragmen
|
||||
* A facade that is used to analyze common (platform-independent) modules in multi-platform projects.
|
||||
* See [TargetPlatform.Default]
|
||||
*/
|
||||
object DefaultAnalyzerFacade : AnalyzerFacade<PlatformAnalysisParameters>() {
|
||||
object DefaultAnalyzerFacade : AnalyzerFacade() {
|
||||
private class SourceModuleInfo(
|
||||
override val name: Name,
|
||||
override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>,
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfigu
|
||||
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil
|
||||
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
|
||||
|
||||
object JsAnalyzerFacade : AnalyzerFacade<PlatformAnalysisParameters>() {
|
||||
object JsAnalyzerFacade : AnalyzerFacade() {
|
||||
|
||||
override fun <M : ModuleInfo> createResolverForModule(
|
||||
moduleInfo: M,
|
||||
|
||||
@@ -22,13 +22,12 @@ import org.jetbrains.kotlin.idea.caches.resolve.JsAnalyzerFacade
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
|
||||
object AnalyzerFacadeProvider {
|
||||
//NOTE: it's convenient that JS backend doesn't have platform parameters (for now)
|
||||
// otherwise we would be forced to add casts on the call site of setupResolverForProject
|
||||
fun getAnalyzerFacade(targetPlatform: TargetPlatform): AnalyzerFacade<JvmPlatformParameters> {
|
||||
fun getAnalyzerFacade(targetPlatform: TargetPlatform): AnalyzerFacade {
|
||||
return when (targetPlatform) {
|
||||
JvmPlatform -> JvmAnalyzerFacade
|
||||
JsPlatform -> JsAnalyzerFacade
|
||||
|
||||
Reference in New Issue
Block a user