Changes after review
- Replace leaking ModuleResolverTracker with use of ModuleDescriptor.Capabilies - Provide API for retrieving ResolverForProject from ResolutionFacade - Update names
This commit is contained in:
-38
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.idea.caches.resolve
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analyzer.ModuleResolverTracker
|
||||
import org.jetbrains.kotlin.analyzer.ResolverForProject
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.project.useAnchorServices
|
||||
|
||||
class IdeaModuleResolverTrackerImpl(private val project: Project) : ModuleResolverTracker<IdeaModuleInfo>() {
|
||||
private val resolversForModules by lazy {
|
||||
mutableMapOf<ModuleDescriptor, ResolverForProject<IdeaModuleInfo>>()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun registerModuleUpdate(
|
||||
newModule: ModuleDescriptor,
|
||||
oldModule: ModuleDescriptor?,
|
||||
resolverForProject: ResolverForProject<IdeaModuleInfo>
|
||||
) {
|
||||
if (!project.useAnchorServices) return
|
||||
|
||||
if (oldModule != null) resolversForModules.remove(oldModule)
|
||||
resolversForModules[newModule] = resolverForProject
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun findResolverForProjectByModuleDescriptor(moduleDescriptor: ModuleDescriptor): ResolverForProject<IdeaModuleInfo>? {
|
||||
if (!project.useAnchorServices) return null
|
||||
|
||||
return resolversForModules[moduleDescriptor]
|
||||
}
|
||||
}
|
||||
+22
-21
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
|
||||
import org.jetbrains.kotlin.caches.resolve.CompositeAnalyzerServices
|
||||
import org.jetbrains.kotlin.caches.resolve.CompositeResolverForModuleFactory
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.caches.resolve.resolution
|
||||
import org.jetbrains.kotlin.context.ProjectContext
|
||||
import org.jetbrains.kotlin.context.withModule
|
||||
@@ -32,7 +33,7 @@ import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.AnchorProvider
|
||||
import org.jetbrains.kotlin.resolve.ResolutionAnchorProvider
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -53,7 +54,7 @@ class IdeaResolverForProject(
|
||||
fallbackModificationTracker,
|
||||
delegateResolver,
|
||||
ServiceManager.getService(projectContext.project, IdePackageOracleFactory::class.java),
|
||||
ServiceManager.getService(projectContext.project, AnchorProvider::class.java)
|
||||
ServiceManager.getService(projectContext.project, ResolutionAnchorProvider::class.java)
|
||||
) {
|
||||
private val builtInsCache: BuiltInsCache =
|
||||
(delegateResolver as? IdeaResolverForProject)?.builtInsCache ?: BuiltInsCache(projectContext, this)
|
||||
@@ -149,32 +150,32 @@ class IdeaResolverForProject(
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerModuleDescriptorUpdate(
|
||||
newDescriptor: ModuleDescriptor,
|
||||
oldDescriptor: ModuleDescriptor?
|
||||
) {
|
||||
ModuleResolverTracker
|
||||
.getInstance(projectContext.project)
|
||||
.safeAs<IdeaModuleResolverTrackerImpl>()
|
||||
?.registerModuleUpdate(newDescriptor, oldDescriptor, this)
|
||||
}
|
||||
|
||||
override fun tryGetResolverForModuleWithAnchorCheck(
|
||||
override fun tryGetResolverForModuleWithResolutionAnchorFallback(
|
||||
targetModuleInfo: IdeaModuleInfo,
|
||||
referencingModuleInfo: IdeaModuleInfo,
|
||||
): ResolverForModule? {
|
||||
tryGetResolverForModule(targetModuleInfo)?.let { return it }
|
||||
|
||||
return getResolverForProjectUsingResolutionAnchor(targetModuleInfo, referencingModuleInfo)
|
||||
}
|
||||
|
||||
private fun getResolverForProjectUsingResolutionAnchor(
|
||||
targetModuleInfo: IdeaModuleInfo,
|
||||
referencingModuleInfo: IdeaModuleInfo
|
||||
): ResolverForModule? {
|
||||
val moduleDescriptorOfReferencingModule = descriptorByModule[referencingModuleInfo]?.moduleDescriptor
|
||||
?: error("$referencingModuleInfo is not contained in this resolver, which means incorrect use of anchor-aware search")
|
||||
|
||||
val anchorModuleDescriptor = anchorProvider.getAnchor(moduleDescriptorOfReferencingModule) ?: return null
|
||||
|
||||
val moduleResolverTracker =
|
||||
ModuleResolverTracker.getInstance(projectContext.project).safeAs<IdeaModuleResolverTrackerImpl>() ?: return null
|
||||
|
||||
return moduleResolverTracker.findResolverForProjectByModuleDescriptor(anchorModuleDescriptor)
|
||||
?.tryGetResolverForModule(targetModuleInfo)
|
||||
|
||||
val anchorModuleInfo = resolutionAnchorProvider.getResolutionAnchor(moduleDescriptorOfReferencingModule)?.moduleInfo ?: return null
|
||||
|
||||
val resolverForProjectFromAnchorModule = KotlinCacheService.getInstance(projectContext.project)
|
||||
.getResolutionFacadeByModuleInfo(anchorModuleInfo, anchorModuleInfo.platform)
|
||||
?.getResolverForProject()
|
||||
?: return null
|
||||
|
||||
if (resolverForProjectFromAnchorModule !is IdeaResolverForProject) return null
|
||||
|
||||
return resolverForProjectFromAnchorModule.tryGetResolverForModule(targetModuleInfo)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-20
@@ -12,23 +12,25 @@ import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ModuleResolverTracker
|
||||
import org.jetbrains.kotlin.analyzer.moduleInfo
|
||||
import org.jetbrains.kotlin.caches.project.cacheInvalidatingOnRootModifications
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.project.*
|
||||
import org.jetbrains.kotlin.idea.project.useAnchorServices
|
||||
import org.jetbrains.kotlin.resolve.AnchorProvider
|
||||
import org.jetbrains.kotlin.idea.project.libraryToSourceAnalysisEnabled
|
||||
import org.jetbrains.kotlin.resolve.ResolutionAnchorProvider
|
||||
|
||||
@State(name = "KotlinIdeAnchorService", storages = [Storage("anchors.xml")])
|
||||
class KotlinIdeAnchorService(
|
||||
class KotlinIdeResolutionAnchorService(
|
||||
val project: Project
|
||||
) : AnchorProvider(),
|
||||
PersistentStateComponent<KotlinIdeAnchorService.State> {
|
||||
) : ResolutionAnchorProvider,
|
||||
PersistentStateComponent<KotlinIdeResolutionAnchorService.State> {
|
||||
|
||||
data class State(
|
||||
var moduleNameToAnchorName: Map<String, String> = emptyMap()
|
||||
)
|
||||
|
||||
private val logger = logger<KotlinIdeResolutionAnchorService>()
|
||||
|
||||
@JvmField
|
||||
var myState: State = State()
|
||||
@@ -50,7 +52,7 @@ class KotlinIdeAnchorService(
|
||||
}
|
||||
|
||||
private fun notFoundModule(moduleName: String): Nothing? {
|
||||
logger<KotlinIdeAnchorService>().warn("Module <${moduleName}> not found in project model")
|
||||
logger.warn("Module <${moduleName}> not found in project model")
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -59,13 +61,6 @@ class KotlinIdeAnchorService(
|
||||
buildMapping()
|
||||
}
|
||||
|
||||
private fun getAnchorModuleDescriptorIfAny(moduleInfo: ModuleInfo): ModuleDescriptor? {
|
||||
val mapped = moduleToAnchor[moduleInfo] ?: return null
|
||||
return KotlinCacheService.getInstance(project)
|
||||
.getResolutionFacadeByModuleInfo(mapped, mapped.platform)
|
||||
?.moduleDescriptor
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun getState(): State = myState
|
||||
|
||||
@@ -75,11 +70,12 @@ class KotlinIdeAnchorService(
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun getAnchor(moduleDescriptor: ModuleDescriptor): ModuleDescriptor? {
|
||||
if (!project.useAnchorServices) return null
|
||||
val resolver = ModuleResolverTracker.getInstance(project)
|
||||
.findResolverForProjectByModuleDescriptor(moduleDescriptor)
|
||||
?: return null
|
||||
return getAnchorModuleDescriptorIfAny(resolver.moduleInfoForModuleDescriptor(moduleDescriptor))
|
||||
override fun getResolutionAnchor(moduleDescriptor: ModuleDescriptor): ModuleDescriptor? {
|
||||
if (!project.libraryToSourceAnalysisEnabled) return null
|
||||
val moduleInfo = moduleDescriptor.moduleInfo ?: return null
|
||||
val mapped = moduleToAnchor[moduleInfo] ?: return null
|
||||
return KotlinCacheService.getInstance(project)
|
||||
.getResolutionFacadeByModuleInfo(mapped, mapped.platform)
|
||||
?.moduleDescriptor
|
||||
}
|
||||
}
|
||||
+5
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.caches.resolve
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.analyzer.ResolverForProject
|
||||
import org.jetbrains.kotlin.container.get
|
||||
import org.jetbrains.kotlin.container.getService
|
||||
import org.jetbrains.kotlin.container.tryGetService
|
||||
@@ -115,6 +116,10 @@ internal class ModuleResolutionFacadeImpl(
|
||||
override fun <T : Any> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
|
||||
return projectFacade.resolverForDescriptor(moduleDescriptor).componentProvider.getService(serviceClass)
|
||||
}
|
||||
|
||||
override fun getResolverForProject(): ResolverForProject<IdeaModuleInfo> {
|
||||
return projectFacade.getResolverForProject()
|
||||
}
|
||||
}
|
||||
|
||||
fun ResolutionFacade.findModuleDescriptor(ideaModuleInfo: IdeaModuleInfo): ModuleDescriptor {
|
||||
|
||||
+2
@@ -145,6 +145,8 @@ internal class ProjectResolutionFacade(
|
||||
internal fun findModuleDescriptor(ideaModuleInfo: IdeaModuleInfo): ModuleDescriptor {
|
||||
return cachedResolverForProject.descriptorForModule(ideaModuleInfo)
|
||||
}
|
||||
|
||||
internal fun getResolverForProject(): ResolverForProject<IdeaModuleInfo> = cachedResolverForProject
|
||||
|
||||
internal fun getAnalysisResultsForElements(elements: Collection<KtElement>): AnalysisResult {
|
||||
assert(elements.isNotEmpty()) { "elements collection should not be empty" }
|
||||
|
||||
+5
@@ -14,6 +14,7 @@ import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.ResolverForProject
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
@@ -89,6 +90,10 @@ private class ResolutionFacadeWithDebugInfo(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getResolverForProject(): ResolverForProject<out ModuleInfo> {
|
||||
return delegate.getResolverForProject()
|
||||
}
|
||||
|
||||
override fun <T : Any> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
|
||||
return wrapExceptions({ ResolvingWhat(serviceClass = serviceClass, moduleDescriptor = moduleDescriptor) }) {
|
||||
delegate.getFrontendService(moduleDescriptor, serviceClass)
|
||||
|
||||
+2
-4
@@ -6,10 +6,8 @@
|
||||
package org.jetbrains.kotlin.idea.caches.resolve.util
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import org.jetbrains.kotlin.context.GlobalContextImpl
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.PlatformAnalysisSettings
|
||||
import org.jetbrains.kotlin.idea.project.useAnchorServices
|
||||
import org.jetbrains.kotlin.idea.project.libraryToSourceAnalysisEnabled
|
||||
import org.jetbrains.kotlin.idea.project.useCompositeAnalysis
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.storage.ExceptionTracker
|
||||
@@ -34,7 +32,7 @@ private fun GlobalContextImpl.contextWithNewLockAndCompositeExceptionTracker(deb
|
||||
}
|
||||
|
||||
internal fun GlobalContextImpl.contextWithCompositeExceptionTracker(project: Project, debugName: String): GlobalContextImpl =
|
||||
if (project.useCompositeAnalysis || project.useAnchorServices) {
|
||||
if (project.useCompositeAnalysis || project.libraryToSourceAnalysisEnabled) {
|
||||
this.contextWithCompositeExceptionTracker(debugName)
|
||||
} else {
|
||||
this.contextWithNewLockAndCompositeExceptionTracker(debugName)
|
||||
|
||||
+6
-6
@@ -8,18 +8,18 @@ package org.jetbrains.kotlin.idea.project
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.openapi.project.Project
|
||||
|
||||
object KotlinAnchorSupportForLibraryAnalysisComponent {
|
||||
private const val anchorSupportOption = "kotlin.use.anchor.services"
|
||||
object KotlinLibraryToSourceAnalysisComponent {
|
||||
private const val libraryToSourceAnalysisOption = "kotlin.library.to.source.analysis"
|
||||
|
||||
@JvmStatic
|
||||
fun setState(project: Project, isEnabled: Boolean) {
|
||||
PropertiesComponent.getInstance(project).setValue(anchorSupportOption, isEnabled, false)
|
||||
PropertiesComponent.getInstance(project).setValue(libraryToSourceAnalysisOption, isEnabled, false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isEnabled(project: Project): Boolean =
|
||||
PropertiesComponent.getInstance(project).getBoolean(anchorSupportOption)
|
||||
PropertiesComponent.getInstance(project).getBoolean(libraryToSourceAnalysisOption)
|
||||
}
|
||||
|
||||
val Project.useAnchorServices: Boolean
|
||||
get() = KotlinAnchorSupportForLibraryAnalysisComponent.isEnabled(this)
|
||||
val Project.libraryToSourceAnalysisEnabled: Boolean
|
||||
get() = KotlinLibraryToSourceAnalysisComponent.isEnabled(this)
|
||||
Reference in New Issue
Block a user