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:
@@ -54,7 +54,6 @@ abstract class ResolverForProject<M : ModuleInfo> {
|
||||
|
||||
abstract val name: String
|
||||
abstract val allModules: Collection<M>
|
||||
abstract val builtInsProvider: (M) -> KotlinBuiltIns
|
||||
|
||||
override fun toString() = name
|
||||
|
||||
@@ -79,7 +78,6 @@ class EmptyResolverForProject<M : ModuleInfo> : ResolverForProject<M>() {
|
||||
override fun descriptorForModule(moduleInfo: M) = diagnoseUnknownModuleInfo(listOf(moduleInfo))
|
||||
override val allModules: Collection<M> = listOf()
|
||||
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>(
|
||||
@@ -128,7 +126,7 @@ class LazyModuleDependencies<M : ModuleInfo>(
|
||||
storageManager: StorageManager,
|
||||
private val module: M,
|
||||
firstDependency: M? = null,
|
||||
private val resolverForProject: ResolverForProjectImpl<M>
|
||||
private val resolverForProject: AbstractResolverForProject<M>
|
||||
) : ModuleDependencies {
|
||||
private val dependencies = storageManager.createLazyValue {
|
||||
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.Name
|
||||
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 projectContext: ProjectContext,
|
||||
protected val projectContext: ProjectContext,
|
||||
modules: Collection<M>,
|
||||
private val modulesContent: (M) -> ModuleContent<M>,
|
||||
private val moduleLanguageSettingsProvider: LanguageSettingsProvider,
|
||||
private val resolverForModuleFactoryByPlatform: (TargetPlatform?) -> ResolverForModuleFactory,
|
||||
private val invalidateOnOOCB: Boolean,
|
||||
override val builtInsProvider: (M) -> KotlinBuiltIns,
|
||||
private val fallbackModificationTracker: ModificationTracker? = null,
|
||||
private val delegateResolver: ResolverForProject<M> = EmptyResolverForProject(),
|
||||
private val sdkDependency: (M) -> M?,
|
||||
private val packageOracleFactory: PackageOracleFactory = PackageOracleFactory.OptimisticFactory,
|
||||
private val isReleaseCoroutines: Boolean? = null
|
||||
private val packageOracleFactory: PackageOracleFactory = PackageOracleFactory.OptimisticFactory
|
||||
) : ResolverForProject<M>() {
|
||||
|
||||
private class ModuleData(
|
||||
@@ -58,6 +53,11 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
||||
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? {
|
||||
if (!isCorrectModuleInfo(moduleInfo)) {
|
||||
return null
|
||||
@@ -108,25 +108,9 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
||||
resolverByModuleDescriptor.getOrPut(descriptor) {
|
||||
checkModuleIsCorrect(module)
|
||||
|
||||
ResolverForModuleComputationTracker.getInstance(projectContext.project)
|
||||
?.onResolverComputed(module)
|
||||
ResolverForModuleComputationTracker.getInstance(projectContext.project)?.onResolverComputed(module)
|
||||
|
||||
val moduleContent = modulesContent(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
|
||||
)
|
||||
createResolverForModule(descriptor, module)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,7 +137,7 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
||||
|
||||
private fun doGetDescriptorForModule(module: M): ModuleDescriptorImpl {
|
||||
val moduleFromThisResolver = moduleInfoToResolvableInfo[module]
|
||||
?: return delegateResolver.descriptorForModule(module) as ModuleDescriptorImpl
|
||||
?: return delegateResolver.descriptorForModule(module) as ModuleDescriptorImpl
|
||||
|
||||
return projectContext.storageManager.compute {
|
||||
var moduleData = descriptorByModule.getOrPut(moduleFromThisResolver) {
|
||||
@@ -183,24 +167,20 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
||||
val moduleDescriptor = ModuleDescriptorImpl(
|
||||
module.name,
|
||||
projectContext.storageManager,
|
||||
builtInsProvider(module),
|
||||
builtInsForModule(module),
|
||||
module.platform,
|
||||
module.capabilities,
|
||||
module.stableName
|
||||
)
|
||||
moduleInfoByDescriptor[moduleDescriptor] = module
|
||||
setupModuleDescriptor(module, moduleDescriptor)
|
||||
val modificationTracker = (module as? TrackableModuleInfo)?.createModificationTracker() ?: if (invalidateOnOOCB) {
|
||||
KotlinModificationTrackerService.getInstance(projectContext.project).outOfBlockModificationTracker
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val modificationTracker = (module as? TrackableModuleInfo)?.createModificationTracker() ?: fallbackModificationTracker
|
||||
return ModuleData(moduleDescriptor, modificationTracker)
|
||||
}
|
||||
}
|
||||
|
||||
private class DelegatingPackageFragmentProvider<M : ModuleInfo>(
|
||||
private val resolverForProject: ResolverForProjectImpl<M>,
|
||||
private val resolverForProject: AbstractResolverForProject<M>,
|
||||
private val module: ModuleDescriptor,
|
||||
moduleContent: ModuleContent<M>,
|
||||
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
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user