From aafe7e6f1b3b6740c3de3c4256a2b78a93f262fa Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 26 Jul 2017 15:23:51 +0200 Subject: [PATCH] Refactoring: move createResolverForModule() into ResolverForProjectImpl --- .../kotlin/resolve/jvm/JvmAnalyzerFacade.kt | 6 +- .../kotlin/analyzer/AnalyzerFacade.kt | 80 +++++++++++-------- .../analyzer/common/DefaultAnalyzerFacade.kt | 2 +- .../kotlin/caches/resolve/JsAnalyzerFacade.kt | 2 +- .../idea/project/AnalyzerFacadeProvider.kt | 3 +- 5 files changed, 53 insertions(+), 40 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt index 79dce65dfdc..8a7b4ea4eb5 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt @@ -43,13 +43,13 @@ class JvmPlatformParameters( ) : PlatformAnalysisParameters -object JvmAnalyzerFacade : AnalyzerFacade() { +object JvmAnalyzerFacade : AnalyzerFacade() { override fun createResolverForModule( moduleInfo: M, moduleDescriptor: ModuleDescriptorImpl, moduleContext: ModuleContext, moduleContent: ModuleContent, - platformParameters: JvmPlatformParameters, + platformParameters: PlatformAnalysisParameters, targetEnvironment: TargetEnvironment, resolverForProject: ResolverForProject, languageSettingsProvider: LanguageSettingsProvider, @@ -64,7 +64,7 @@ object JvmAnalyzerFacade : AnalyzerFacade() { ) 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 diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt index c45fce6ae18..d5fb3bec39e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt @@ -75,6 +75,12 @@ class EmptyResolverForProject : ResolverForProject() { } class ResolverForProjectImpl( + 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, private val delegateResolver: ResolverForProject = EmptyResolverForProject() @@ -86,7 +92,17 @@ class ResolverForProjectImpl( return resolverForModuleDescriptor(doGetDescriptorForModule(moduleInfo)) } - internal val resolverByModuleDescriptor: MutableMap> = HashMap() + internal val resolverByModuleDescriptor: Map> = 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 by lazy { (descriptorByModule.keys + delegateResolver.allModules).toSet() @@ -156,15 +172,15 @@ interface ModuleInfo { } } -abstract class AnalyzerFacade { +abstract class AnalyzerFacade { companion object { - fun

setupResolverForProject( + fun setupResolverForProject( debugName: String, projectContext: ProjectContext, modules: Collection, - analyzerFacade: (M) -> AnalyzerFacade

, + 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 { ): ResolverForProject { 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 { 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 createResolverForModule( + abstract fun createResolverForModule( moduleInfo: M, moduleDescriptor: ModuleDescriptorImpl, moduleContext: ModuleContext, moduleContent: ModuleContent, - platformParameters: P, + platformParameters: PlatformAnalysisParameters, targetEnvironment: TargetEnvironment, resolverForProject: ResolverForProject, languageSettingsProvider: LanguageSettingsProvider, @@ -272,27 +282,31 @@ class LazyModuleDependencies( } -private class DelegatingPackageFragmentProvider( +private class DelegatingPackageFragmentProvider( + private val resolverForProject: ResolverForProjectImpl, + private val module: ModuleDescriptor, moduleContent: ModuleContent, - private val packageOracle: PackageOracle, - private val resolverForModule: NotNullLazyValue + private val packageOracle: PackageOracle ) : PackageFragmentProvider { private val syntheticFilePackages = moduleContent.syntheticFiles.map { it.packageFqName }.toSet() override fun getPackageFragments(fqName: FqName): List { 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 { 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 } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt index f0280c1720f..70399366a43 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt @@ -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() { +object DefaultAnalyzerFacade : AnalyzerFacade() { private class SourceModuleInfo( override val name: Name, override val capabilities: Map, Any?>, diff --git a/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/JsAnalyzerFacade.kt b/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/JsAnalyzerFacade.kt index 960bb5b1c20..76ec714bb2e 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/JsAnalyzerFacade.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/JsAnalyzerFacade.kt @@ -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() { +object JsAnalyzerFacade : AnalyzerFacade() { override fun createResolverForModule( moduleInfo: M, diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/AnalyzerFacadeProvider.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/AnalyzerFacadeProvider.kt index 95738930637..5cc9209f14f 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/AnalyzerFacadeProvider.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/AnalyzerFacadeProvider.kt @@ -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 { + fun getAnalyzerFacade(targetPlatform: TargetPlatform): AnalyzerFacade { return when (targetPlatform) { JvmPlatform -> JvmAnalyzerFacade JsPlatform -> JsAnalyzerFacade