Refactoring: move createResolverForModule() into ResolverForProjectImpl
This commit is contained in:
@@ -43,13 +43,13 @@ class JvmPlatformParameters(
|
|||||||
) : PlatformAnalysisParameters
|
) : PlatformAnalysisParameters
|
||||||
|
|
||||||
|
|
||||||
object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
|
object JvmAnalyzerFacade : AnalyzerFacade() {
|
||||||
override fun <M : ModuleInfo> createResolverForModule(
|
override fun <M : ModuleInfo> createResolverForModule(
|
||||||
moduleInfo: M,
|
moduleInfo: M,
|
||||||
moduleDescriptor: ModuleDescriptorImpl,
|
moduleDescriptor: ModuleDescriptorImpl,
|
||||||
moduleContext: ModuleContext,
|
moduleContext: ModuleContext,
|
||||||
moduleContent: ModuleContent,
|
moduleContent: ModuleContent,
|
||||||
platformParameters: JvmPlatformParameters,
|
platformParameters: PlatformAnalysisParameters,
|
||||||
targetEnvironment: TargetEnvironment,
|
targetEnvironment: TargetEnvironment,
|
||||||
resolverForProject: ResolverForProject<M>,
|
resolverForProject: ResolverForProject<M>,
|
||||||
languageSettingsProvider: LanguageSettingsProvider,
|
languageSettingsProvider: LanguageSettingsProvider,
|
||||||
@@ -64,7 +64,7 @@ object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val moduleClassResolver = ModuleClassResolverImpl { javaClass ->
|
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.
|
// 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)
|
// 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
|
// 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>(
|
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 debugName: String,
|
||||||
private val descriptorByModule: Map<M, ModuleDescriptorImpl>,
|
private val descriptorByModule: Map<M, ModuleDescriptorImpl>,
|
||||||
private val delegateResolver: ResolverForProject<M> = EmptyResolverForProject()
|
private val delegateResolver: ResolverForProject<M> = EmptyResolverForProject()
|
||||||
@@ -86,7 +92,17 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
|||||||
return resolverForModuleDescriptor(doGetDescriptorForModule(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 {
|
override val allModules: Collection<M> by lazy {
|
||||||
(descriptorByModule.keys + delegateResolver.allModules).toSet()
|
(descriptorByModule.keys + delegateResolver.allModules).toSet()
|
||||||
@@ -156,15 +172,15 @@ interface ModuleInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
abstract class AnalyzerFacade {
|
||||||
companion object {
|
companion object {
|
||||||
fun <P : PlatformAnalysisParameters, M : ModuleInfo> setupResolverForProject(
|
fun <M : ModuleInfo> setupResolverForProject(
|
||||||
debugName: String,
|
debugName: String,
|
||||||
projectContext: ProjectContext,
|
projectContext: ProjectContext,
|
||||||
modules: Collection<M>,
|
modules: Collection<M>,
|
||||||
analyzerFacade: (M) -> AnalyzerFacade<P>,
|
analyzerFacade: (M) -> AnalyzerFacade,
|
||||||
modulesContent: (M) -> ModuleContent,
|
modulesContent: (M) -> ModuleContent,
|
||||||
platformParameters: P,
|
platformParameters: PlatformAnalysisParameters,
|
||||||
languageSettingsProvider: LanguageSettingsProvider = LanguageSettingsProvider.Default,
|
languageSettingsProvider: LanguageSettingsProvider = LanguageSettingsProvider.Default,
|
||||||
targetEnvironment: TargetEnvironment = CompilerEnvironment,
|
targetEnvironment: TargetEnvironment = CompilerEnvironment,
|
||||||
builtIns: KotlinBuiltIns = DefaultBuiltIns.Instance,
|
builtIns: KotlinBuiltIns = DefaultBuiltIns.Instance,
|
||||||
@@ -176,9 +192,17 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
|||||||
): ResolverForProject<M> {
|
): ResolverForProject<M> {
|
||||||
val storageManager = projectContext.storageManager
|
val storageManager = projectContext.storageManager
|
||||||
|
|
||||||
val resolverForProject = ResolverForProjectImpl(debugName, modules.keysToMap { module ->
|
val resolverForProject = ResolverForProjectImpl(
|
||||||
ModuleDescriptorImpl(module.name, storageManager, builtIns, modulePlatforms(module), module.capabilities)
|
projectContext,
|
||||||
}, delegateResolver)
|
analyzerFacade,
|
||||||
|
modulesContent,
|
||||||
|
platformParameters,
|
||||||
|
targetEnvironment,
|
||||||
|
packagePartProviderFactory,
|
||||||
|
debugName,
|
||||||
|
modules.keysToMap { module ->
|
||||||
|
ModuleDescriptorImpl(module.name, storageManager, builtIns, modulePlatforms(module), module.capabilities)
|
||||||
|
}, delegateResolver)
|
||||||
|
|
||||||
for (module in modules) {
|
for (module in modules) {
|
||||||
val moduleDescriptor = resolverForProject.descriptorForModule(module)
|
val moduleDescriptor = resolverForProject.descriptorForModule(module)
|
||||||
@@ -188,37 +212,23 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
|
|||||||
modulePlatforms,
|
modulePlatforms,
|
||||||
firstDependency,
|
firstDependency,
|
||||||
resolverForProject))
|
resolverForProject))
|
||||||
}
|
|
||||||
|
|
||||||
for (module in modules) {
|
|
||||||
val descriptor = resolverForProject.descriptorForModule(module)
|
|
||||||
val content = modulesContent(module)
|
val content = modulesContent(module)
|
||||||
val computeResolverForModule = storageManager.createLazyValue {
|
moduleDescriptor.initialize(
|
||||||
ResolverForModuleComputationTracker.getInstance(projectContext.project)?.onResolverComputed(module)
|
DelegatingPackageFragmentProvider(resolverForProject, moduleDescriptor, content,
|
||||||
|
packageOracleFactory.createOracle(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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolverForProject
|
return resolverForProject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun <M : ModuleInfo> createResolverForModule(
|
abstract fun <M : ModuleInfo> createResolverForModule(
|
||||||
moduleInfo: M,
|
moduleInfo: M,
|
||||||
moduleDescriptor: ModuleDescriptorImpl,
|
moduleDescriptor: ModuleDescriptorImpl,
|
||||||
moduleContext: ModuleContext,
|
moduleContext: ModuleContext,
|
||||||
moduleContent: ModuleContent,
|
moduleContent: ModuleContent,
|
||||||
platformParameters: P,
|
platformParameters: PlatformAnalysisParameters,
|
||||||
targetEnvironment: TargetEnvironment,
|
targetEnvironment: TargetEnvironment,
|
||||||
resolverForProject: ResolverForProject<M>,
|
resolverForProject: ResolverForProject<M>,
|
||||||
languageSettingsProvider: LanguageSettingsProvider,
|
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,
|
moduleContent: ModuleContent,
|
||||||
private val packageOracle: PackageOracle,
|
private val packageOracle: PackageOracle
|
||||||
private val resolverForModule: NotNullLazyValue<ResolverForModule>
|
|
||||||
) : PackageFragmentProvider {
|
) : PackageFragmentProvider {
|
||||||
private val syntheticFilePackages = moduleContent.syntheticFiles.map { it.packageFqName }.toSet()
|
private val syntheticFilePackages = moduleContent.syntheticFiles.map { it.packageFqName }.toSet()
|
||||||
|
|
||||||
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> {
|
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> {
|
||||||
if (certainlyDoesNotExist(fqName)) return emptyList()
|
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> {
|
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> {
|
||||||
if (certainlyDoesNotExist(fqName)) return emptyList()
|
if (certainlyDoesNotExist(fqName)) return emptyList()
|
||||||
|
|
||||||
return resolverForModule().packageFragmentProvider.getSubPackagesOf(fqName, nameFilter)
|
return resolverForModuleCachedValue().packageFragmentProvider.getSubPackagesOf(fqName, nameFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun certainlyDoesNotExist(fqName: FqName): Boolean {
|
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
|
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.
|
* A facade that is used to analyze common (platform-independent) modules in multi-platform projects.
|
||||||
* See [TargetPlatform.Default]
|
* See [TargetPlatform.Default]
|
||||||
*/
|
*/
|
||||||
object DefaultAnalyzerFacade : AnalyzerFacade<PlatformAnalysisParameters>() {
|
object DefaultAnalyzerFacade : AnalyzerFacade() {
|
||||||
private class SourceModuleInfo(
|
private class SourceModuleInfo(
|
||||||
override val name: Name,
|
override val name: Name,
|
||||||
override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>,
|
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.serialization.js.KotlinJavascriptSerializationUtil
|
||||||
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
|
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
|
||||||
|
|
||||||
object JsAnalyzerFacade : AnalyzerFacade<PlatformAnalysisParameters>() {
|
object JsAnalyzerFacade : AnalyzerFacade() {
|
||||||
|
|
||||||
override fun <M : ModuleInfo> createResolverForModule(
|
override fun <M : ModuleInfo> createResolverForModule(
|
||||||
moduleInfo: M,
|
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.js.resolve.JsPlatform
|
||||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade
|
import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||||
|
|
||||||
object AnalyzerFacadeProvider {
|
object AnalyzerFacadeProvider {
|
||||||
//NOTE: it's convenient that JS backend doesn't have platform parameters (for now)
|
//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
|
// 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) {
|
return when (targetPlatform) {
|
||||||
JvmPlatform -> JvmAnalyzerFacade
|
JvmPlatform -> JvmAnalyzerFacade
|
||||||
JsPlatform -> JsAnalyzerFacade
|
JsPlatform -> JsAnalyzerFacade
|
||||||
|
|||||||
Reference in New Issue
Block a user