Refactoring: remove ModuleResolverProvider, inline createModuleResolverProvider
This commit is contained in:
@@ -62,6 +62,7 @@ abstract class ResolverForProject<M : ModuleInfo> {
|
||||
|
||||
abstract val name: String
|
||||
abstract val allModules: Collection<M>
|
||||
abstract val builtIns: KotlinBuiltIns
|
||||
|
||||
override fun toString() = name
|
||||
}
|
||||
@@ -77,6 +78,7 @@ 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 builtIns get() = DefaultBuiltIns.Instance
|
||||
}
|
||||
|
||||
class ResolverForProjectImpl<M : ModuleInfo>(
|
||||
@@ -87,7 +89,7 @@ class ResolverForProjectImpl<M : ModuleInfo>(
|
||||
private val modulesContent: (M) -> ModuleContent,
|
||||
private val platformParameters: PlatformAnalysisParameters,
|
||||
private val targetEnvironment: TargetEnvironment = CompilerEnvironment,
|
||||
private val builtIns: KotlinBuiltIns = DefaultBuiltIns.Instance,
|
||||
override val builtIns: KotlinBuiltIns = DefaultBuiltIns.Instance,
|
||||
private val delegateResolver: ResolverForProject<M> = EmptyResolverForProject(),
|
||||
private val packagePartProviderFactory: (M, ModuleContent) -> PackagePartProvider = { _, _ -> PackagePartProvider.Empty },
|
||||
private val firstDependency: M? = null,
|
||||
|
||||
-115
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.caches.resolve
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analyzer.ModuleContent
|
||||
import org.jetbrains.kotlin.analyzer.ResolverForProject
|
||||
import org.jetbrains.kotlin.analyzer.ResolverForProjectImpl
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.caches.resolve.IdePlatformSupport
|
||||
import org.jetbrains.kotlin.context.GlobalContextImpl
|
||||
import org.jetbrains.kotlin.context.withProject
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
||||
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.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||
import org.jetbrains.kotlin.platform.JvmBuiltIns
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
|
||||
|
||||
fun createModuleResolverProvider(
|
||||
debugName: String,
|
||||
project: Project,
|
||||
globalContext: GlobalContextImpl,
|
||||
analysisSettings: PlatformAnalysisSettings,
|
||||
syntheticFiles: Collection<KtFile>,
|
||||
delegateResolver: ResolverForProject<IdeaModuleInfo>,
|
||||
moduleFilter: (IdeaModuleInfo) -> Boolean,
|
||||
allModules: Collection<IdeaModuleInfo>,
|
||||
providedBuiltIns: KotlinBuiltIns?, // null means create new builtins based on SDK
|
||||
dependencies: Collection<Any>,
|
||||
invalidateOnOOCB: Boolean = true
|
||||
): ModuleResolverProvider {
|
||||
val builtIns = providedBuiltIns ?: createBuiltIns(analysisSettings, globalContext)
|
||||
|
||||
val allModuleInfos = allModules.toMutableSet()
|
||||
|
||||
val syntheticFilesByModule = syntheticFiles.groupBy(KtFile::getModuleInfo)
|
||||
val syntheticFilesModules = syntheticFilesByModule.keys
|
||||
allModuleInfos.addAll(syntheticFilesModules)
|
||||
|
||||
val modulesToCreateResolversFor = allModuleInfos.filter(moduleFilter)
|
||||
|
||||
val modulesContent = { module: IdeaModuleInfo ->
|
||||
ModuleContent(syntheticFilesByModule[module] ?: listOf(), module.contentScope())
|
||||
}
|
||||
|
||||
val jvmPlatformParameters = JvmPlatformParameters { javaClass: JavaClass ->
|
||||
val psiClass = (javaClass as JavaClassImpl).psi
|
||||
psiClass.getNullableModuleInfo()
|
||||
}
|
||||
|
||||
val resolverForProject = ResolverForProjectImpl(
|
||||
debugName, globalContext.withProject(project), modulesToCreateResolversFor,
|
||||
{ module ->
|
||||
val platform = module.platform ?: analysisSettings.platform
|
||||
IdePlatformSupport.facades[platform] ?: throw UnsupportedOperationException("Unsupported platform $platform")
|
||||
},
|
||||
modulesContent, jvmPlatformParameters,
|
||||
IdeaEnvironment, builtIns,
|
||||
delegateResolver, { _, c -> IDEPackagePartProvider(c.moduleContentScope) },
|
||||
analysisSettings.sdk?.let { SdkInfo(project, it) },
|
||||
modulePlatforms = { module -> module.platform?.multiTargetPlatform },
|
||||
packageOracleFactory = ServiceManager.getService(project, IdePackageOracleFactory::class.java),
|
||||
languageSettingsProvider = IDELanguageSettingsProvider,
|
||||
invalidateOnOOCB = invalidateOnOOCB
|
||||
)
|
||||
|
||||
if (providedBuiltIns == null && builtIns is JvmBuiltIns) {
|
||||
val sdkModuleDescriptor = analysisSettings.sdk!!.let { resolverForProject.descriptorForModule(
|
||||
SdkInfo(
|
||||
project,
|
||||
it
|
||||
)
|
||||
) }
|
||||
builtIns.initialize(sdkModuleDescriptor, analysisSettings.isAdditionalBuiltInFeaturesSupported)
|
||||
}
|
||||
|
||||
return ModuleResolverProvider(
|
||||
resolverForProject,
|
||||
builtIns,
|
||||
dependencies + listOf(globalContext.exceptionTracker)
|
||||
)
|
||||
}
|
||||
|
||||
private fun createBuiltIns(settings: PlatformAnalysisSettings, sdkContext: GlobalContextImpl): KotlinBuiltIns {
|
||||
val supportInstance = IdePlatformSupport.platformSupport[settings.platform] ?: return DefaultBuiltIns.Instance
|
||||
return supportInstance.createBuiltIns(settings, sdkContext)
|
||||
}
|
||||
|
||||
class ModuleResolverProvider(
|
||||
val resolverForProject: ResolverForProject<IdeaModuleInfo>,
|
||||
val builtIns: KotlinBuiltIns,
|
||||
val cacheDependencies: Collection<Any>
|
||||
)
|
||||
+114
-48
@@ -16,21 +16,30 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.caches.resolve
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import com.intellij.util.containers.SLRUCache
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.analyzer.EmptyResolverForProject
|
||||
import org.jetbrains.kotlin.analyzer.ResolverForModule
|
||||
import org.jetbrains.kotlin.analyzer.*
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.caches.resolve.IdePlatformSupport
|
||||
import org.jetbrains.kotlin.context.GlobalContextImpl
|
||||
import org.jetbrains.kotlin.context.withProject
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.project.*
|
||||
import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
||||
import org.jetbrains.kotlin.idea.project.IdeaEnvironment
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||
import org.jetbrains.kotlin.platform.JvmBuiltIns
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.CompositeBindingContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
internal class ProjectResolutionFacade(
|
||||
@@ -41,7 +50,7 @@ internal class ProjectResolutionFacade(
|
||||
val settings: PlatformAnalysisSettings,
|
||||
val reuseDataFrom: ProjectResolutionFacade?,
|
||||
val moduleFilter: (IdeaModuleInfo) -> Boolean,
|
||||
val dependencies: List<Any>,
|
||||
dependencies: List<Any>,
|
||||
private val invalidateOnOOCB: Boolean,
|
||||
val syntheticFiles: Collection<KtFile> = listOf(),
|
||||
val allModules: Collection<IdeaModuleInfo>? = null // null means create resolvers for modules from idea model
|
||||
@@ -49,66 +58,115 @@ internal class ProjectResolutionFacade(
|
||||
private val cachedValue = CachedValuesManager.getManager(project).createCachedValue(
|
||||
{
|
||||
val resolverProvider = computeModuleResolverProvider()
|
||||
CachedValueProvider.Result.create(resolverProvider, resolverProvider.cacheDependencies)
|
||||
CachedValueProvider.Result.create(resolverProvider, resolverForProjectDependencies)
|
||||
},
|
||||
/* trackValue = */ false
|
||||
)
|
||||
|
||||
private fun computeModuleResolverProvider(): ModuleResolverProvider {
|
||||
val delegateResolverProvider = reuseDataFrom?.moduleResolverProvider
|
||||
val delegateResolverForProject = delegateResolverProvider?.resolverForProject ?: EmptyResolverForProject()
|
||||
return createModuleResolverProvider(
|
||||
resolverDebugName,
|
||||
project,
|
||||
globalContext,
|
||||
settings,
|
||||
syntheticFiles = syntheticFiles,
|
||||
delegateResolver = delegateResolverForProject,
|
||||
moduleFilter = moduleFilter,
|
||||
allModules = allModules ?: collectAllModuleInfosFromIdeaModel(project),
|
||||
providedBuiltIns = delegateResolverProvider?.builtIns,
|
||||
dependencies = dependencies,
|
||||
invalidateOnOOCB = invalidateOnOOCB
|
||||
)
|
||||
}
|
||||
|
||||
private val moduleResolverProvider: ModuleResolverProvider
|
||||
private val cachedResolverForProject: ResolverForProject<IdeaModuleInfo>
|
||||
get() = globalContext.storageManager.compute { cachedValue.value }
|
||||
|
||||
private val resolverForProject get() = moduleResolverProvider.resolverForProject
|
||||
|
||||
fun resolverForModuleInfo(moduleInfo: IdeaModuleInfo) = resolverForProject.resolverForModule(moduleInfo)
|
||||
|
||||
fun resolverForElement(element: PsiElement): ResolverForModule {
|
||||
val infos = element.getModuleInfos()
|
||||
return infos.asIterable().firstNotNullResult { resolverForProject.tryGetResolverForModule(it) }
|
||||
?: resolverForProject.tryGetResolverForModule(NotUnderContentRootModuleInfo)
|
||||
?: resolverForProject.diagnoseUnknownModuleInfo(infos.toList())
|
||||
}
|
||||
|
||||
fun resolverForDescriptor(moduleDescriptor: ModuleDescriptor) = resolverForProject.resolverForModuleDescriptor(moduleDescriptor)
|
||||
|
||||
fun findModuleDescriptor(ideaModuleInfo: IdeaModuleInfo): ModuleDescriptor {
|
||||
return resolverForProject.descriptorForModule(ideaModuleInfo)
|
||||
}
|
||||
|
||||
private val analysisResults = CachedValuesManager.getManager(project).createCachedValue(
|
||||
{
|
||||
val resolverProvider = moduleResolverProvider
|
||||
val resolverForProject = cachedResolverForProject
|
||||
val results = object : SLRUCache<KtFile, PerFileAnalysisCache>(2, 3) {
|
||||
override fun createValue(file: KtFile): PerFileAnalysisCache {
|
||||
return PerFileAnalysisCache(
|
||||
file,
|
||||
resolverProvider.resolverForProject.resolverForModule(file.getModuleInfo()).componentProvider
|
||||
resolverForProject.resolverForModule(file.getModuleInfo()).componentProvider
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val allDependencies = resolverProvider.cacheDependencies + listOf(PsiModificationTracker.MODIFICATION_COUNT)
|
||||
val allDependencies = resolverForProjectDependencies + listOf(PsiModificationTracker.MODIFICATION_COUNT)
|
||||
CachedValueProvider.Result.create(results, allDependencies)
|
||||
}, false
|
||||
)
|
||||
|
||||
private val resolverForProjectDependencies = dependencies + listOf(globalContext.exceptionTracker)
|
||||
|
||||
private fun computeModuleResolverProvider(): ResolverForProject<IdeaModuleInfo> {
|
||||
val delegateResolverForProject: ResolverForProject<IdeaModuleInfo>
|
||||
val delegateBuiltIns: KotlinBuiltIns?
|
||||
|
||||
if (reuseDataFrom != null) {
|
||||
delegateResolverForProject = reuseDataFrom.cachedResolverForProject
|
||||
delegateBuiltIns = delegateResolverForProject.builtIns
|
||||
} else {
|
||||
delegateResolverForProject = EmptyResolverForProject()
|
||||
delegateBuiltIns = null
|
||||
}
|
||||
|
||||
val builtIns = delegateBuiltIns ?: createBuiltIns(
|
||||
settings,
|
||||
globalContext
|
||||
)
|
||||
|
||||
val allModuleInfos = (allModules ?: collectAllModuleInfosFromIdeaModel(project)).toMutableSet()
|
||||
|
||||
val syntheticFilesByModule = syntheticFiles.groupBy(KtFile::getModuleInfo)
|
||||
val syntheticFilesModules = syntheticFilesByModule.keys
|
||||
allModuleInfos.addAll(syntheticFilesModules)
|
||||
|
||||
val modulesToCreateResolversFor = allModuleInfos.filter(moduleFilter)
|
||||
|
||||
val modulesContentFactory = { module: IdeaModuleInfo ->
|
||||
ModuleContent(syntheticFilesByModule[module] ?: listOf(), module.contentScope())
|
||||
}
|
||||
|
||||
val jvmPlatformParameters = JvmPlatformParameters { javaClass: JavaClass ->
|
||||
val psiClass = (javaClass as JavaClassImpl).psi
|
||||
psiClass.getNullableModuleInfo()
|
||||
}
|
||||
|
||||
val resolverForProject = ResolverForProjectImpl(
|
||||
resolverDebugName,
|
||||
globalContext.withProject(project),
|
||||
modulesToCreateResolversFor,
|
||||
{ module ->
|
||||
val platform = module.platform ?: settings.platform
|
||||
IdePlatformSupport.facades[platform] ?: throw UnsupportedOperationException("Unsupported platform $platform")
|
||||
},
|
||||
modulesContentFactory,
|
||||
jvmPlatformParameters,
|
||||
IdeaEnvironment,
|
||||
builtIns,
|
||||
delegateResolverForProject,
|
||||
packagePartProviderFactory = { _, c -> IDEPackagePartProvider(c.moduleContentScope) },
|
||||
firstDependency = settings.sdk?.let { SdkInfo(project, it) },
|
||||
modulePlatforms = { module -> module.platform?.multiTargetPlatform },
|
||||
packageOracleFactory = ServiceManager.getService(project, IdePackageOracleFactory::class.java),
|
||||
languageSettingsProvider = IDELanguageSettingsProvider,
|
||||
invalidateOnOOCB = invalidateOnOOCB
|
||||
)
|
||||
|
||||
if (delegateBuiltIns == null && builtIns is JvmBuiltIns) {
|
||||
val sdkModuleDescriptor = settings.sdk!!.let {
|
||||
resolverForProject.descriptorForModule(
|
||||
SdkInfo(project, it)
|
||||
)
|
||||
}
|
||||
builtIns.initialize(sdkModuleDescriptor, settings.isAdditionalBuiltInFeaturesSupported)
|
||||
}
|
||||
|
||||
return resolverForProject
|
||||
}
|
||||
|
||||
fun resolverForModuleInfo(moduleInfo: IdeaModuleInfo) = cachedResolverForProject.resolverForModule(moduleInfo)
|
||||
|
||||
fun resolverForElement(element: PsiElement): ResolverForModule {
|
||||
val infos = element.getModuleInfos()
|
||||
return infos.asIterable().firstNotNullResult { cachedResolverForProject.tryGetResolverForModule(it) }
|
||||
?: cachedResolverForProject.tryGetResolverForModule(NotUnderContentRootModuleInfo)
|
||||
?: cachedResolverForProject.diagnoseUnknownModuleInfo(infos.toList())
|
||||
}
|
||||
|
||||
fun resolverForDescriptor(moduleDescriptor: ModuleDescriptor) = cachedResolverForProject.resolverForModuleDescriptor(moduleDescriptor)
|
||||
|
||||
fun findModuleDescriptor(ideaModuleInfo: IdeaModuleInfo): ModuleDescriptor {
|
||||
return cachedResolverForProject.descriptorForModule(ideaModuleInfo)
|
||||
}
|
||||
|
||||
fun getAnalysisResultsForElements(elements: Collection<KtElement>): AnalysisResult {
|
||||
assert(elements.isNotEmpty()) { "elements collection should not be empty" }
|
||||
val slruCache = synchronized(analysisResults) {
|
||||
@@ -122,14 +180,22 @@ internal class ProjectResolutionFacade(
|
||||
}
|
||||
val withError = results.firstOrNull { it.isError() }
|
||||
val bindingContext = CompositeBindingContext.create(results.map { it.bindingContext })
|
||||
return if (withError != null)
|
||||
AnalysisResult.internalError(bindingContext, withError.error)
|
||||
else
|
||||
if (withError != null) {
|
||||
return AnalysisResult.internalError(bindingContext, withError.error)
|
||||
}
|
||||
|
||||
//TODO: (module refactoring) several elements are passed here in debugger
|
||||
AnalysisResult.success(bindingContext, findModuleDescriptor(elements.first().getModuleInfo()))
|
||||
return AnalysisResult.success(bindingContext, findModuleDescriptor(elements.first().getModuleInfo()))
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "$debugString@${Integer.toHexString(hashCode())}"
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun createBuiltIns(settings: PlatformAnalysisSettings, sdkContext: GlobalContextImpl): KotlinBuiltIns {
|
||||
val supportInstance = IdePlatformSupport.platformSupport[settings.platform] ?: return DefaultBuiltIns.Instance
|
||||
return supportInstance.createBuiltIns(settings, sdkContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user