Improve ResolutionFacade api: it stores moduleInfo and provides moduleDescriptor
Remove some redundant parameters passed along with ResolutionFacade
This commit is contained in:
@@ -38,7 +38,7 @@ public fun JetExpression.computeTypeInfoInContext(
|
||||
expectedType: JetType = TypeUtils.NO_EXPECTED_TYPE,
|
||||
isStatement: Boolean = false
|
||||
): JetTypeInfo {
|
||||
return contextExpression.getResolutionFacade().frontendService<ExpressionTypingServices>(contextExpression)
|
||||
return contextExpression.getResolutionFacade().frontendService<ExpressionTypingServices>()
|
||||
.getTypeInfo(scope, this, expectedType, dataFlowInfo, trace, isStatement)
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -91,9 +91,9 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
|
||||
Collections.sort(sortedFiles, scopeFileComparator);
|
||||
|
||||
JetFile file = sortedFiles.get(0);
|
||||
ResolveSession session = KotlinCacheService.getInstance(file.getProject()).getLazyResolveSession(file);
|
||||
forceResolvePackageDeclarations(files, session);
|
||||
return new LightClassConstructionContext(session.getBindingContext(), session.getModuleDescriptor());
|
||||
ResolveSession resolveSession = ResolvePackage.getResolutionFacade(file).getFrontendService(ResolveSession.class);
|
||||
forceResolvePackageDeclarations(files, resolveSession);
|
||||
return new LightClassConstructionContext(resolveSession.getBindingContext(), resolveSession.getModuleDescriptor());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -101,7 +101,7 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
|
||||
public LightClassConstructionContext getContextForClassOrObject(@NotNull JetClassOrObject classOrObject) {
|
||||
ResolutionFacade resolutionFacade = ResolvePackage.getResolutionFacade(classOrObject);
|
||||
|
||||
ModuleDescriptor moduleDescriptor = resolutionFacade.findModuleDescriptor(classOrObject);
|
||||
ModuleDescriptor moduleDescriptor = resolutionFacade.getModuleDescriptor();
|
||||
BindingContext bindingContext = resolutionFacade.analyze(classOrObject, BodyResolveMode.FULL);
|
||||
if (classOrObject.isLocal()) {
|
||||
ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, classOrObject);
|
||||
|
||||
+1
-2
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.caches.resolve
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.resolve.frontendService
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
@@ -29,7 +28,7 @@ import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
|
||||
private fun PsiElement.getJavaDescriptorResolver(): JavaDescriptorResolver {
|
||||
@suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
|
||||
return KotlinCacheService.getInstance(getProject()).getGlobalFacade(JvmPlatform).frontendService<JavaDescriptorResolver>(this)
|
||||
return KotlinCacheService.getInstance(project).getProjectService(JvmPlatform, this.getModuleInfo(), javaClass<JavaDescriptorResolver>())
|
||||
}
|
||||
|
||||
fun PsiMethod.getJavaMethodDescriptor(): FunctionDescriptor? {
|
||||
|
||||
+19
-25
@@ -25,6 +25,7 @@ import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import com.intellij.util.containers.SLRUCache
|
||||
import org.jetbrains.kotlin.analyzer.EmptyResolverForProject
|
||||
import org.jetbrains.kotlin.container.getService
|
||||
import org.jetbrains.kotlin.idea.project.AnalyzerFacadeProvider
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
@@ -35,7 +36,6 @@ import org.jetbrains.kotlin.psi.JetElement
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import kotlin.platform.platformStatic
|
||||
|
||||
@@ -53,7 +53,7 @@ public class KotlinCacheService(val project: Project) {
|
||||
private val globalFacadesPerPlatform = listOf(JvmPlatform, JsPlatform).keysToMap { platform -> GlobalFacade(platform) }
|
||||
|
||||
private inner class GlobalFacade(platform: TargetPlatform) {
|
||||
val facadeForLibraries = ResolutionFacadeImpl(project) {
|
||||
val facadeForLibraries = ProjectResolutionFacade(project) {
|
||||
globalResolveSessionProvider(
|
||||
project,
|
||||
platform,
|
||||
@@ -66,7 +66,7 @@ public class KotlinCacheService(val project: Project) {
|
||||
)
|
||||
}
|
||||
|
||||
val facadeForModules = ResolutionFacadeImpl(project) {
|
||||
val facadeForModules = ProjectResolutionFacade(project) {
|
||||
globalResolveSessionProvider(
|
||||
project,
|
||||
platform,
|
||||
@@ -77,13 +77,15 @@ public class KotlinCacheService(val project: Project) {
|
||||
}
|
||||
|
||||
deprecated("Use JetElement.getResolutionFacade(), please avoid introducing new usages")
|
||||
public fun getGlobalFacade(platform: TargetPlatform): ResolutionFacade = globalFacade(platform)
|
||||
public fun <T> getProjectService(platform: TargetPlatform, ideaModuleInfo: IdeaModuleInfo, serviceClass: Class<T>): T {
|
||||
return globalFacade(platform).resolverForModuleInfo(ideaModuleInfo).componentProvider.getService(serviceClass)
|
||||
}
|
||||
|
||||
private fun globalFacade(platform: TargetPlatform) = globalFacadesPerPlatform[platform]!!.facadeForModules
|
||||
|
||||
private fun librariesFacade(platform: TargetPlatform) = globalFacadesPerPlatform[platform]!!.facadeForLibraries
|
||||
|
||||
private fun createFacadeForSyntheticFiles(files: Set<JetFile>): ResolutionFacadeImpl {
|
||||
private fun createFacadeForSyntheticFiles(files: Set<JetFile>): ProjectResolutionFacade {
|
||||
// we assume that all files come from the same module
|
||||
val targetPlatform = files.map { TargetPlatformDetector.getPlatform(it) }.toSet().single()
|
||||
val syntheticFileModule = files.map { it.getModuleInfo() }.toSet().single()
|
||||
@@ -94,7 +96,7 @@ public class KotlinCacheService(val project: Project) {
|
||||
return when {
|
||||
syntheticFileModule is ModuleSourceInfo -> {
|
||||
val dependentModules = syntheticFileModule.getDependentModules()
|
||||
ResolutionFacadeImpl(project) {
|
||||
ProjectResolutionFacade(project) {
|
||||
globalResolveSessionProvider(
|
||||
project,
|
||||
targetPlatform,
|
||||
@@ -107,7 +109,7 @@ public class KotlinCacheService(val project: Project) {
|
||||
}
|
||||
|
||||
syntheticFileModule is LibrarySourceInfo || syntheticFileModule is NotUnderContentRootModuleInfo -> {
|
||||
ResolutionFacadeImpl(project) {
|
||||
ProjectResolutionFacade(project) {
|
||||
globalResolveSessionProvider(
|
||||
project,
|
||||
targetPlatform,
|
||||
@@ -124,7 +126,7 @@ public class KotlinCacheService(val project: Project) {
|
||||
// currently the only known scenario is when we cannot determine that file is a library source
|
||||
// (file under both classes and sources root)
|
||||
LOG.warn("Creating cache with synthetic files ($files) in classes of library $syntheticFileModule")
|
||||
ResolutionFacadeImpl(project) {
|
||||
ProjectResolutionFacade(project) {
|
||||
globalResolveSessionProvider(
|
||||
project,
|
||||
targetPlatform,
|
||||
@@ -142,14 +144,14 @@ public class KotlinCacheService(val project: Project) {
|
||||
private val syntheticFileCachesLock = Any()
|
||||
|
||||
private val slruCacheProvider = CachedValueProvider {
|
||||
CachedValueProvider.Result(object : SLRUCache<Set<JetFile>, ResolutionFacadeImpl>(2, 3) {
|
||||
override fun createValue(files: Set<JetFile>): ResolutionFacadeImpl {
|
||||
CachedValueProvider.Result(object : SLRUCache<Set<JetFile>, ProjectResolutionFacade>(2, 3) {
|
||||
override fun createValue(files: Set<JetFile>): ProjectResolutionFacade {
|
||||
return createFacadeForSyntheticFiles(files)
|
||||
}
|
||||
}, LibraryModificationTracker.getInstance(project), ProjectRootModificationTracker.getInstance(project))
|
||||
}
|
||||
|
||||
private fun getFacadeForSyntheticFiles(files: Set<JetFile>): ResolutionFacadeImpl {
|
||||
private fun getFacadeForSyntheticFiles(files: Set<JetFile>): ProjectResolutionFacade {
|
||||
return synchronized(syntheticFileCachesLock) {
|
||||
//NOTE: computations inside createCacheForSyntheticFiles depend on project root structure
|
||||
// so we additionally drop the whole slru cache on change
|
||||
@@ -157,24 +159,16 @@ public class KotlinCacheService(val project: Project) {
|
||||
}
|
||||
}
|
||||
|
||||
public fun getLazyResolveSession(element: JetElement): ResolveSession {
|
||||
val file = element.getContainingJetFile()
|
||||
return getFacadeToAnalyzeFiles(listOf(file)).getLazyResolveSession(file)
|
||||
}
|
||||
|
||||
private fun getFacadeToAnalyzeFiles(files: Collection<JetFile>): ResolutionFacadeImpl {
|
||||
private fun getFacadeToAnalyzeFiles(files: Collection<JetFile>): ResolutionFacade {
|
||||
val syntheticFiles = findSyntheticFiles(files)
|
||||
return if (syntheticFiles.isNotEmpty()) {
|
||||
val file = files.first()
|
||||
val projectFacade = if (syntheticFiles.isNotEmpty()) {
|
||||
getFacadeForSyntheticFiles(syntheticFiles)
|
||||
}
|
||||
else {
|
||||
val firstFile = files.firstOrNull()
|
||||
val targetPlatform = if (firstFile != null)
|
||||
TargetPlatformDetector.getPlatform(firstFile)
|
||||
else
|
||||
TargetPlatformDetector.getDefaultPlatform()
|
||||
globalFacade(targetPlatform)
|
||||
globalFacade(TargetPlatformDetector.getPlatform(file))
|
||||
}
|
||||
return ResolutionFacadeImpl(projectFacade, file.getModuleInfo())
|
||||
}
|
||||
|
||||
private fun findSyntheticFiles(files: Collection<JetFile>) = files.map {
|
||||
@@ -196,7 +190,7 @@ private fun globalResolveSessionProvider(
|
||||
platform: TargetPlatform,
|
||||
dependencies: Collection<Any>,
|
||||
moduleFilter: (IdeaModuleInfo) -> Boolean,
|
||||
reuseDataFrom: ResolutionFacadeImpl? = null,
|
||||
reuseDataFrom: ProjectResolutionFacade? = null,
|
||||
syntheticFiles: Collection<JetFile> = listOf(),
|
||||
logProcessCanceled: Boolean = false
|
||||
): CachedValueProvider.Result<ModuleResolverProvider> {
|
||||
|
||||
+53
-41
@@ -37,53 +37,20 @@ import org.jetbrains.kotlin.resolve.CompositeBindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
|
||||
private class ResolutionFacadeImpl(
|
||||
override val project: Project,
|
||||
private class ProjectResolutionFacade(
|
||||
val project: Project,
|
||||
computeModuleResolverProvider: () -> CachedValueProvider.Result<ModuleResolverProvider>
|
||||
) : ResolutionFacade {
|
||||
) {
|
||||
private val resolverCache = SynchronizedCachedValue(project, computeModuleResolverProvider, trackValue = false)
|
||||
|
||||
val moduleResolverProvider: ModuleResolverProvider
|
||||
get() = resolverCache.getValue()
|
||||
|
||||
public fun getLazyResolveSession(element: JetElement): ResolveSession {
|
||||
return resolverForModuleInfo(element.getModuleInfo()).componentProvider.get<ResolveSession>()
|
||||
}
|
||||
fun resolverForModuleInfo(moduleInfo: IdeaModuleInfo) = moduleResolverProvider.resolverForProject.resolverForModule(moduleInfo)
|
||||
fun resolverForDescriptor(moduleDescriptor: ModuleDescriptor) = moduleResolverProvider.resolverForProject.resolverForModuleDescriptor(moduleDescriptor)
|
||||
|
||||
private fun resolverForModuleInfo(moduleInfo: IdeaModuleInfo) = moduleResolverProvider.resolverForProject.resolverForModule(moduleInfo)
|
||||
private fun resolverForDescriptor(moduleDescriptor: ModuleDescriptor) = moduleResolverProvider.resolverForProject.resolverForModuleDescriptor(moduleDescriptor)
|
||||
|
||||
override fun <T> getFrontendService(element: PsiElement, serviceClass: Class<T>): T {
|
||||
return resolverForModuleInfo(element.getModuleInfo()).componentProvider.getService(serviceClass)
|
||||
}
|
||||
|
||||
override fun <T> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
|
||||
return resolverForDescriptor(moduleDescriptor).componentProvider.getService(serviceClass)
|
||||
}
|
||||
|
||||
override fun <T> getIdeService(element: PsiElement, serviceClass: Class<T>): T {
|
||||
return resolverForModuleInfo(element.getModuleInfo()).componentProvider.create(serviceClass)
|
||||
}
|
||||
|
||||
override fun <T> getIdeService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
|
||||
return resolverForDescriptor(moduleDescriptor).componentProvider.create(serviceClass)
|
||||
}
|
||||
|
||||
override fun analyze(element: JetElement, bodyResolveMode: BodyResolveMode): BindingContext {
|
||||
val resolveElementCache = getFrontendService(element, javaClass<ResolveElementCache>())
|
||||
return resolveElementCache.resolveToElement(element, bodyResolveMode)
|
||||
}
|
||||
|
||||
override fun findModuleDescriptor(element: JetElement): ModuleDescriptor {
|
||||
return moduleResolverProvider.resolverForProject.descriptorForModule(element.getModuleInfo())
|
||||
}
|
||||
|
||||
override fun resolveToDescriptor(declaration: JetDeclaration): DeclarationDescriptor {
|
||||
return getLazyResolveSession(declaration).resolveToDescriptor(declaration)
|
||||
}
|
||||
|
||||
override fun analyzeFullyAndGetResult(elements: Collection<JetElement>): AnalysisResult {
|
||||
return getAnalysisResultsForElements(elements)
|
||||
fun findModuleDescriptor(ideaModuleInfo: IdeaModuleInfo): ModuleDescriptor {
|
||||
return moduleResolverProvider.resolverForProject.descriptorForModule(ideaModuleInfo)
|
||||
}
|
||||
|
||||
private val analysisResults = CachedValuesManager.getManager(project).createCachedValue(
|
||||
@@ -114,6 +81,51 @@ private class ResolutionFacadeImpl(
|
||||
AnalysisResult.error(bindingContext, withError.error)
|
||||
else
|
||||
//TODO: (module refactoring) several elements are passed here in debugger
|
||||
AnalysisResult.success(bindingContext, getLazyResolveSession(elements.first()).getModuleDescriptor())
|
||||
AnalysisResult.success(bindingContext, findModuleDescriptor(elements.first().getModuleInfo()))
|
||||
}
|
||||
}
|
||||
|
||||
private class ResolutionFacadeImpl(
|
||||
private val projectFacade: ProjectResolutionFacade,
|
||||
private val moduleInfo: IdeaModuleInfo
|
||||
) : ResolutionFacade {
|
||||
override val project: Project
|
||||
get() = projectFacade.project
|
||||
|
||||
//TODO: ideally we would like to store moduleDescriptor once and for all
|
||||
// but there are some usages that use resolutionFacade and mutate the psi leading to recomputation of underlying structures
|
||||
override val moduleDescriptor: ModuleDescriptor
|
||||
get() = projectFacade.findModuleDescriptor(moduleInfo)
|
||||
|
||||
override fun analyze(element: JetElement, bodyResolveMode: BodyResolveMode): BindingContext {
|
||||
val resolveElementCache = getFrontendService(element, javaClass<ResolveElementCache>())
|
||||
return resolveElementCache.resolveToElement(element, bodyResolveMode)
|
||||
}
|
||||
|
||||
override fun analyzeFullyAndGetResult(elements: Collection<JetElement>): AnalysisResult
|
||||
= projectFacade.getAnalysisResultsForElements(elements)
|
||||
|
||||
override fun resolveToDescriptor(declaration: JetDeclaration): DeclarationDescriptor {
|
||||
val resolveSession = projectFacade.resolverForModuleInfo(declaration.getModuleInfo()).componentProvider.get<ResolveSession>()
|
||||
return resolveSession.resolveToDescriptor(declaration)
|
||||
}
|
||||
|
||||
override fun <T> getFrontendService(serviceClass: Class<T>): T = getFrontendService(moduleInfo, serviceClass)
|
||||
|
||||
override fun <T> getIdeService(serviceClass: Class<T>): T {
|
||||
return projectFacade.resolverForModuleInfo(moduleInfo).componentProvider.create(serviceClass)
|
||||
}
|
||||
|
||||
override fun <T> getFrontendService(element: PsiElement, serviceClass: Class<T>): T {
|
||||
return getFrontendService(element.getModuleInfo(), serviceClass)
|
||||
}
|
||||
|
||||
fun <T> getFrontendService(ideaModuleInfo: IdeaModuleInfo, serviceClass: Class<T>): T {
|
||||
return projectFacade.resolverForModuleInfo(ideaModuleInfo).componentProvider.getService(serviceClass)
|
||||
}
|
||||
|
||||
override fun <T> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
|
||||
return projectFacade.resolverForDescriptor(moduleDescriptor).componentProvider.getService(serviceClass)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public fun JetDeclaration.resolveToDescriptor(): DeclarationDescriptor {
|
||||
|
||||
public fun JetFile.resolveImportReference(fqName: FqName): Collection<DeclarationDescriptor> {
|
||||
val facade = getResolutionFacade()
|
||||
return facade.resolveImportReference(project, facade.findModuleDescriptor(this), fqName)
|
||||
return facade.resolveImportReference(facade.moduleDescriptor, fqName)
|
||||
}
|
||||
|
||||
//NOTE: the difference between analyze and analyzeFully is 'intentionally' unclear
|
||||
@@ -61,11 +61,11 @@ public fun JetElement.analyze(bodyResolveMode: BodyResolveMode = BodyResolveMode
|
||||
|
||||
public fun JetElement.analyzeAndGetResult(): AnalysisResult {
|
||||
val resolutionFacade = getResolutionFacade()
|
||||
return AnalysisResult.success(resolutionFacade.analyze(this), resolutionFacade.findModuleDescriptor(this))
|
||||
return AnalysisResult.success(resolutionFacade.analyze(this), resolutionFacade.moduleDescriptor)
|
||||
}
|
||||
|
||||
public fun JetElement.findModuleDescriptor(): ModuleDescriptor {
|
||||
return getResolutionFacade().findModuleDescriptor(this)
|
||||
return getResolutionFacade().moduleDescriptor
|
||||
}
|
||||
|
||||
public fun JetElement.analyzeFully(): BindingContext {
|
||||
@@ -77,12 +77,11 @@ public fun JetElement.analyzeFullyAndGetResult(vararg extraFiles: JetFile): Anal
|
||||
}
|
||||
|
||||
public fun ResolutionFacade.resolveImportReference(
|
||||
project: Project,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
fqName: FqName
|
||||
): Collection<DeclarationDescriptor> {
|
||||
val importDirective = JetPsiFactory(project).createImportDirective(ImportPath(fqName, false))
|
||||
val qualifiedExpressionResolver = this.frontendService<QualifiedExpressionResolver>(moduleDescriptor)
|
||||
val qualifiedExpressionResolver = this.getFrontendService(moduleDescriptor, javaClass<QualifiedExpressionResolver>())
|
||||
return qualifiedExpressionResolver.processImportReference(
|
||||
importDirective, moduleDescriptor, BindingTraceContext(), QualifiedExpressionResolver.LookupMode.EVERYTHING).getAllDescriptors()
|
||||
}
|
||||
@@ -98,5 +97,5 @@ public fun getResolveScope(file: JetFile): GlobalSearchScope {
|
||||
}
|
||||
|
||||
public fun ResolutionFacade.getFileTopLevelScope(file: JetFile): JetScope {
|
||||
return frontendService<FileScopeProvider>(file).getFileScope(file)
|
||||
return frontendService<FileScopeProvider>().getFileScope(file)
|
||||
}
|
||||
Reference in New Issue
Block a user