Improve ResolutionFacade api: it stores moduleInfo and provides moduleDescriptor

Remove some redundant parameters passed along with ResolutionFacade
This commit is contained in:
Pavel V. Talanov
2015-08-20 17:47:37 +03:00
parent a802ab5300
commit 608345df7b
27 changed files with 151 additions and 162 deletions
@@ -110,10 +110,9 @@ public class ReferenceVariantsHelper(
val dataFlowInfo = context.getDataFlowInfo(expression) val dataFlowInfo = context.getDataFlowInfo(expression)
val smartCastManager = resolutionFacade.frontendService<SmartCastManager>(expression) val smartCastManager = resolutionFacade.frontendService<SmartCastManager>()
val implicitReceiverTypes = resolutionScope.getImplicitReceiversWithInstance().flatMap { val implicitReceiverTypes = resolutionScope.getImplicitReceiversWithInstance().flatMap {
smartCastManager smartCastManager.getSmartCastVariantsWithLessSpecificExcluded(it.value, context, containingDeclaration, dataFlowInfo)
.getSmartCastVariantsWithLessSpecificExcluded(it.value, context, containingDeclaration, dataFlowInfo)
}.toSet() }.toSet()
val pair = getExplicitReceiverData(expression) val pair = getExplicitReceiverData(expression)
@@ -35,25 +35,22 @@ public interface ResolutionFacade {
public fun resolveToDescriptor(declaration: JetDeclaration): DeclarationDescriptor public fun resolveToDescriptor(declaration: JetDeclaration): DeclarationDescriptor
public fun findModuleDescriptor(element: JetElement): ModuleDescriptor public val moduleDescriptor: ModuleDescriptor
// get service for the module this resolution was created for
public fun <T> getFrontendService(serviceClass: Class<T>): T
public fun <T> getIdeService(serviceClass: Class<T>): T
// get service for the module defined by PsiElement/ModuleDescriptor passed as parameter
public fun <T> getFrontendService(element: PsiElement, serviceClass: Class<T>): T public fun <T> getFrontendService(element: PsiElement, serviceClass: Class<T>): T
public fun <T> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T public fun <T> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T
public fun <T> getIdeService(element: PsiElement, serviceClass: Class<T>): T
public fun <T> getIdeService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T
} }
public inline fun <reified T> ResolutionFacade.frontendService(element: PsiElement): T public inline fun <reified T> ResolutionFacade.frontendService(): T
= this.getFrontendService(element, javaClass<T>()) = this.getFrontendService(javaClass<T>())
public inline fun <reified T> ResolutionFacade.frontendService(moduleDescriptor: ModuleDescriptor): T public inline fun <reified T> ResolutionFacade.ideService(): T
= this.getFrontendService(moduleDescriptor, javaClass<T>()) = this.getIdeService(javaClass<T>())
public inline fun <reified T> ResolutionFacade.ideService(element: PsiElement): T
= this.getIdeService(element, javaClass<T>())
public inline fun <reified T> ResolutionFacade.ideService(moduleDescriptor: ModuleDescriptor): T
= this.getIdeService(moduleDescriptor, javaClass<T>())
@@ -165,7 +165,7 @@ public class ShadowedDeclarationsFilter(
val context = BasicCallResolutionContext.create(bindingTrace, resolutionScope, newCall, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, val context = BasicCallResolutionContext.create(bindingTrace, resolutionScope, newCall, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo,
ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
CallChecker.DoNothing, false) CallChecker.DoNothing, false)
val callResolver = resolutionFacade.frontendService<CallResolver>(calleeExpression) val callResolver = resolutionFacade.frontendService<CallResolver>()
val results = if (isFunction) callResolver.resolveFunctionCall(context) else callResolver.resolveSimpleProperty(context) val results = if (isFunction) callResolver.resolveFunctionCall(context) else callResolver.resolveSimpleProperty(context)
val resultingDescriptors = results.getResultingCalls().map { it.getResultingDescriptor() } val resultingDescriptors = results.getResultingCalls().map { it.getResultingDescriptor() }
val resultingOriginals = resultingDescriptors.mapTo(HashSet<DeclarationDescriptor>()) { it.getOriginal() } val resultingOriginals = resultingDescriptors.mapTo(HashSet<DeclarationDescriptor>()) { it.getOriginal() }
@@ -38,7 +38,7 @@ public fun JetExpression.computeTypeInfoInContext(
expectedType: JetType = TypeUtils.NO_EXPECTED_TYPE, expectedType: JetType = TypeUtils.NO_EXPECTED_TYPE,
isStatement: Boolean = false isStatement: Boolean = false
): JetTypeInfo { ): JetTypeInfo {
return contextExpression.getResolutionFacade().frontendService<ExpressionTypingServices>(contextExpression) return contextExpression.getResolutionFacade().frontendService<ExpressionTypingServices>()
.getTypeInfo(scope, this, expectedType, dataFlowInfo, trace, isStatement) .getTypeInfo(scope, this, expectedType, dataFlowInfo, trace, isStatement)
} }
@@ -91,9 +91,9 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
Collections.sort(sortedFiles, scopeFileComparator); Collections.sort(sortedFiles, scopeFileComparator);
JetFile file = sortedFiles.get(0); JetFile file = sortedFiles.get(0);
ResolveSession session = KotlinCacheService.getInstance(file.getProject()).getLazyResolveSession(file); ResolveSession resolveSession = ResolvePackage.getResolutionFacade(file).getFrontendService(ResolveSession.class);
forceResolvePackageDeclarations(files, session); forceResolvePackageDeclarations(files, resolveSession);
return new LightClassConstructionContext(session.getBindingContext(), session.getModuleDescriptor()); return new LightClassConstructionContext(resolveSession.getBindingContext(), resolveSession.getModuleDescriptor());
} }
@NotNull @NotNull
@@ -101,7 +101,7 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
public LightClassConstructionContext getContextForClassOrObject(@NotNull JetClassOrObject classOrObject) { public LightClassConstructionContext getContextForClassOrObject(@NotNull JetClassOrObject classOrObject) {
ResolutionFacade resolutionFacade = ResolvePackage.getResolutionFacade(classOrObject); ResolutionFacade resolutionFacade = ResolvePackage.getResolutionFacade(classOrObject);
ModuleDescriptor moduleDescriptor = resolutionFacade.findModuleDescriptor(classOrObject); ModuleDescriptor moduleDescriptor = resolutionFacade.getModuleDescriptor();
BindingContext bindingContext = resolutionFacade.analyze(classOrObject, BodyResolveMode.FULL); BindingContext bindingContext = resolutionFacade.analyze(classOrObject, BodyResolveMode.FULL);
if (classOrObject.isLocal()) { if (classOrObject.isLocal()) {
ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, classOrObject); ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, classOrObject);
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.caches.resolve
import com.intellij.psi.* import com.intellij.psi.*
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.load.java.structure.*
@@ -29,7 +28,7 @@ import org.jetbrains.kotlin.resolve.scopes.JetScope
private fun PsiElement.getJavaDescriptorResolver(): JavaDescriptorResolver { private fun PsiElement.getJavaDescriptorResolver(): JavaDescriptorResolver {
@suppress("DEPRECATED_SYMBOL_WITH_MESSAGE") @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? { fun PsiMethod.getJavaMethodDescriptor(): FunctionDescriptor? {
@@ -25,6 +25,7 @@ import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.SLRUCache import com.intellij.util.containers.SLRUCache
import org.jetbrains.kotlin.analyzer.EmptyResolverForProject 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.AnalyzerFacadeProvider
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade 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.psi.JetFile
import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.utils.keysToMap import org.jetbrains.kotlin.utils.keysToMap
import kotlin.platform.platformStatic 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 val globalFacadesPerPlatform = listOf(JvmPlatform, JsPlatform).keysToMap { platform -> GlobalFacade(platform) }
private inner class GlobalFacade(platform: TargetPlatform) { private inner class GlobalFacade(platform: TargetPlatform) {
val facadeForLibraries = ResolutionFacadeImpl(project) { val facadeForLibraries = ProjectResolutionFacade(project) {
globalResolveSessionProvider( globalResolveSessionProvider(
project, project,
platform, platform,
@@ -66,7 +66,7 @@ public class KotlinCacheService(val project: Project) {
) )
} }
val facadeForModules = ResolutionFacadeImpl(project) { val facadeForModules = ProjectResolutionFacade(project) {
globalResolveSessionProvider( globalResolveSessionProvider(
project, project,
platform, platform,
@@ -77,13 +77,15 @@ public class KotlinCacheService(val project: Project) {
} }
deprecated("Use JetElement.getResolutionFacade(), please avoid introducing new usages") 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 globalFacade(platform: TargetPlatform) = globalFacadesPerPlatform[platform]!!.facadeForModules
private fun librariesFacade(platform: TargetPlatform) = globalFacadesPerPlatform[platform]!!.facadeForLibraries 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 // we assume that all files come from the same module
val targetPlatform = files.map { TargetPlatformDetector.getPlatform(it) }.toSet().single() val targetPlatform = files.map { TargetPlatformDetector.getPlatform(it) }.toSet().single()
val syntheticFileModule = files.map { it.getModuleInfo() }.toSet().single() val syntheticFileModule = files.map { it.getModuleInfo() }.toSet().single()
@@ -94,7 +96,7 @@ public class KotlinCacheService(val project: Project) {
return when { return when {
syntheticFileModule is ModuleSourceInfo -> { syntheticFileModule is ModuleSourceInfo -> {
val dependentModules = syntheticFileModule.getDependentModules() val dependentModules = syntheticFileModule.getDependentModules()
ResolutionFacadeImpl(project) { ProjectResolutionFacade(project) {
globalResolveSessionProvider( globalResolveSessionProvider(
project, project,
targetPlatform, targetPlatform,
@@ -107,7 +109,7 @@ public class KotlinCacheService(val project: Project) {
} }
syntheticFileModule is LibrarySourceInfo || syntheticFileModule is NotUnderContentRootModuleInfo -> { syntheticFileModule is LibrarySourceInfo || syntheticFileModule is NotUnderContentRootModuleInfo -> {
ResolutionFacadeImpl(project) { ProjectResolutionFacade(project) {
globalResolveSessionProvider( globalResolveSessionProvider(
project, project,
targetPlatform, 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 // currently the only known scenario is when we cannot determine that file is a library source
// (file under both classes and sources root) // (file under both classes and sources root)
LOG.warn("Creating cache with synthetic files ($files) in classes of library $syntheticFileModule") LOG.warn("Creating cache with synthetic files ($files) in classes of library $syntheticFileModule")
ResolutionFacadeImpl(project) { ProjectResolutionFacade(project) {
globalResolveSessionProvider( globalResolveSessionProvider(
project, project,
targetPlatform, targetPlatform,
@@ -142,14 +144,14 @@ public class KotlinCacheService(val project: Project) {
private val syntheticFileCachesLock = Any() private val syntheticFileCachesLock = Any()
private val slruCacheProvider = CachedValueProvider { private val slruCacheProvider = CachedValueProvider {
CachedValueProvider.Result(object : SLRUCache<Set<JetFile>, ResolutionFacadeImpl>(2, 3) { CachedValueProvider.Result(object : SLRUCache<Set<JetFile>, ProjectResolutionFacade>(2, 3) {
override fun createValue(files: Set<JetFile>): ResolutionFacadeImpl { override fun createValue(files: Set<JetFile>): ProjectResolutionFacade {
return createFacadeForSyntheticFiles(files) return createFacadeForSyntheticFiles(files)
} }
}, LibraryModificationTracker.getInstance(project), ProjectRootModificationTracker.getInstance(project)) }, LibraryModificationTracker.getInstance(project), ProjectRootModificationTracker.getInstance(project))
} }
private fun getFacadeForSyntheticFiles(files: Set<JetFile>): ResolutionFacadeImpl { private fun getFacadeForSyntheticFiles(files: Set<JetFile>): ProjectResolutionFacade {
return synchronized(syntheticFileCachesLock) { return synchronized(syntheticFileCachesLock) {
//NOTE: computations inside createCacheForSyntheticFiles depend on project root structure //NOTE: computations inside createCacheForSyntheticFiles depend on project root structure
// so we additionally drop the whole slru cache on change // 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 { private fun getFacadeToAnalyzeFiles(files: Collection<JetFile>): ResolutionFacade {
val file = element.getContainingJetFile()
return getFacadeToAnalyzeFiles(listOf(file)).getLazyResolveSession(file)
}
private fun getFacadeToAnalyzeFiles(files: Collection<JetFile>): ResolutionFacadeImpl {
val syntheticFiles = findSyntheticFiles(files) val syntheticFiles = findSyntheticFiles(files)
return if (syntheticFiles.isNotEmpty()) { val file = files.first()
val projectFacade = if (syntheticFiles.isNotEmpty()) {
getFacadeForSyntheticFiles(syntheticFiles) getFacadeForSyntheticFiles(syntheticFiles)
} }
else { else {
val firstFile = files.firstOrNull() globalFacade(TargetPlatformDetector.getPlatform(file))
val targetPlatform = if (firstFile != null)
TargetPlatformDetector.getPlatform(firstFile)
else
TargetPlatformDetector.getDefaultPlatform()
globalFacade(targetPlatform)
} }
return ResolutionFacadeImpl(projectFacade, file.getModuleInfo())
} }
private fun findSyntheticFiles(files: Collection<JetFile>) = files.map { private fun findSyntheticFiles(files: Collection<JetFile>) = files.map {
@@ -196,7 +190,7 @@ private fun globalResolveSessionProvider(
platform: TargetPlatform, platform: TargetPlatform,
dependencies: Collection<Any>, dependencies: Collection<Any>,
moduleFilter: (IdeaModuleInfo) -> Boolean, moduleFilter: (IdeaModuleInfo) -> Boolean,
reuseDataFrom: ResolutionFacadeImpl? = null, reuseDataFrom: ProjectResolutionFacade? = null,
syntheticFiles: Collection<JetFile> = listOf(), syntheticFiles: Collection<JetFile> = listOf(),
logProcessCanceled: Boolean = false logProcessCanceled: Boolean = false
): CachedValueProvider.Result<ModuleResolverProvider> { ): CachedValueProvider.Result<ModuleResolverProvider> {
@@ -37,53 +37,20 @@ import org.jetbrains.kotlin.resolve.CompositeBindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.resolve.lazy.ResolveSession
private class ResolutionFacadeImpl( private class ProjectResolutionFacade(
override val project: Project, val project: Project,
computeModuleResolverProvider: () -> CachedValueProvider.Result<ModuleResolverProvider> computeModuleResolverProvider: () -> CachedValueProvider.Result<ModuleResolverProvider>
) : ResolutionFacade { ) {
private val resolverCache = SynchronizedCachedValue(project, computeModuleResolverProvider, trackValue = false) private val resolverCache = SynchronizedCachedValue(project, computeModuleResolverProvider, trackValue = false)
val moduleResolverProvider: ModuleResolverProvider val moduleResolverProvider: ModuleResolverProvider
get() = resolverCache.getValue() get() = resolverCache.getValue()
public fun getLazyResolveSession(element: JetElement): ResolveSession { fun resolverForModuleInfo(moduleInfo: IdeaModuleInfo) = moduleResolverProvider.resolverForProject.resolverForModule(moduleInfo)
return resolverForModuleInfo(element.getModuleInfo()).componentProvider.get<ResolveSession>() fun resolverForDescriptor(moduleDescriptor: ModuleDescriptor) = moduleResolverProvider.resolverForProject.resolverForModuleDescriptor(moduleDescriptor)
}
private fun resolverForModuleInfo(moduleInfo: IdeaModuleInfo) = moduleResolverProvider.resolverForProject.resolverForModule(moduleInfo) fun findModuleDescriptor(ideaModuleInfo: IdeaModuleInfo): ModuleDescriptor {
private fun resolverForDescriptor(moduleDescriptor: ModuleDescriptor) = moduleResolverProvider.resolverForProject.resolverForModuleDescriptor(moduleDescriptor) return moduleResolverProvider.resolverForProject.descriptorForModule(ideaModuleInfo)
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)
} }
private val analysisResults = CachedValuesManager.getManager(project).createCachedValue( private val analysisResults = CachedValuesManager.getManager(project).createCachedValue(
@@ -114,6 +81,51 @@ private class ResolutionFacadeImpl(
AnalysisResult.error(bindingContext, withError.error) AnalysisResult.error(bindingContext, withError.error)
else else
//TODO: (module refactoring) several elements are passed here in debugger //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> { public fun JetFile.resolveImportReference(fqName: FqName): Collection<DeclarationDescriptor> {
val facade = getResolutionFacade() 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 //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 { public fun JetElement.analyzeAndGetResult(): AnalysisResult {
val resolutionFacade = getResolutionFacade() 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 { public fun JetElement.findModuleDescriptor(): ModuleDescriptor {
return getResolutionFacade().findModuleDescriptor(this) return getResolutionFacade().moduleDescriptor
} }
public fun JetElement.analyzeFully(): BindingContext { public fun JetElement.analyzeFully(): BindingContext {
@@ -77,12 +77,11 @@ public fun JetElement.analyzeFullyAndGetResult(vararg extraFiles: JetFile): Anal
} }
public fun ResolutionFacade.resolveImportReference( public fun ResolutionFacade.resolveImportReference(
project: Project,
moduleDescriptor: ModuleDescriptor, moduleDescriptor: ModuleDescriptor,
fqName: FqName fqName: FqName
): Collection<DeclarationDescriptor> { ): Collection<DeclarationDescriptor> {
val importDirective = JetPsiFactory(project).createImportDirective(ImportPath(fqName, false)) val importDirective = JetPsiFactory(project).createImportDirective(ImportPath(fqName, false))
val qualifiedExpressionResolver = this.frontendService<QualifiedExpressionResolver>(moduleDescriptor) val qualifiedExpressionResolver = this.getFrontendService(moduleDescriptor, javaClass<QualifiedExpressionResolver>())
return qualifiedExpressionResolver.processImportReference( return qualifiedExpressionResolver.processImportReference(
importDirective, moduleDescriptor, BindingTraceContext(), QualifiedExpressionResolver.LookupMode.EVERYTHING).getAllDescriptors() importDirective, moduleDescriptor, BindingTraceContext(), QualifiedExpressionResolver.LookupMode.EVERYTHING).getAllDescriptors()
} }
@@ -98,5 +97,5 @@ public fun getResolveScope(file: JetFile): GlobalSearchScope {
} }
public fun ResolutionFacade.getFileTopLevelScope(file: JetFile): JetScope { public fun ResolutionFacade.getFileTopLevelScope(file: JetFile): JetScope {
return frontendService<FileScopeProvider>(file).getFileScope(file) return frontendService<FileScopeProvider>().getFileScope(file)
} }
@@ -97,8 +97,10 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
null null
private val smartCompletion = expression?.let { private val smartCompletion = expression?.let {
SmartCompletion(it, resolutionFacade, moduleDescriptor, bindingContext, isVisibleFilter, inDescriptor, prefixMatcher, SmartCompletion(
GlobalSearchScope.EMPTY_SCOPE, toFromOriginalFileMapper, lookupElementFactory, forBasicCompletion = true) it, resolutionFacade, bindingContext, isVisibleFilter, inDescriptor, prefixMatcher,
GlobalSearchScope.EMPTY_SCOPE, toFromOriginalFileMapper, lookupElementFactory, forBasicCompletion = true
)
} }
private fun calcCompletionKind(): CompletionKind { private fun calcCompletionKind(): CompletionKind {
@@ -73,7 +73,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
protected val position: PsiElement = parameters.getPosition() protected val position: PsiElement = parameters.getPosition()
private val file = position.getContainingFile() as JetFile private val file = position.getContainingFile() as JetFile
protected val resolutionFacade: ResolutionFacade = file.getResolutionFacade() protected val resolutionFacade: ResolutionFacade = file.getResolutionFacade()
protected val moduleDescriptor: ModuleDescriptor = resolutionFacade.findModuleDescriptor(file) protected val moduleDescriptor: ModuleDescriptor = resolutionFacade.moduleDescriptor
protected val project: Project = position.getProject() protected val project: Project = position.getProject()
protected val nameExpression: JetSimpleNameExpression? protected val nameExpression: JetSimpleNameExpression?
@@ -148,7 +148,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
var receiverTypes = receiversData.receivers.flatMap { receiverValue -> var receiverTypes = receiversData.receivers.flatMap { receiverValue ->
val dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiverValue, bindingContext, moduleDescriptor) val dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiverValue, bindingContext, moduleDescriptor)
if (dataFlowValue.isPredictable) { // we don't include smart cast receiver types for "unpredictable" receiver value to mark members grayed if (dataFlowValue.isPredictable) { // we don't include smart cast receiver types for "unpredictable" receiver value to mark members grayed
resolutionFacade.frontendService<SmartCastManager>(file) resolutionFacade.frontendService<SmartCastManager>()
.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo) .getSmartCastVariantsWithLessSpecificExcluded(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)
} }
else { else {
@@ -187,7 +187,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
} }
protected val indicesHelper: KotlinIndicesHelper protected val indicesHelper: KotlinIndicesHelper
get() = KotlinIndicesHelper(project, resolutionFacade, searchScope, moduleDescriptor, isVisibleFilter, true) get() = KotlinIndicesHelper(resolutionFacade, searchScope, isVisibleFilter, true)
protected val toFromOriginalFileMapper: ToFromOriginalFileMapper protected val toFromOriginalFileMapper: ToFromOriginalFileMapper
= ToFromOriginalFileMapper(parameters.originalFile as JetFile, position.containingFile as JetFile, parameters.offset) = ToFromOriginalFileMapper(parameters.originalFile as JetFile, position.containingFile as JetFile, parameters.offset)
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.completion.smart.TypesWithContainsDetector import org.jetbrains.kotlin.idea.completion.smart.TypesWithContainsDetector
import org.jetbrains.kotlin.idea.core.IterableTypesDetection import org.jetbrains.kotlin.idea.core.IterableTypesDetection
import org.jetbrains.kotlin.idea.core.IterableTypesDetector
import org.jetbrains.kotlin.idea.core.mapArgumentsToParameters import org.jetbrains.kotlin.idea.core.mapArgumentsToParameters
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.frontendService import org.jetbrains.kotlin.idea.resolve.frontendService
@@ -148,7 +147,6 @@ class ReturnValueAdditionalData(val callable: CallableDescriptor) : ExpectedInfo
class ExpectedInfos( class ExpectedInfos(
val bindingContext: BindingContext, val bindingContext: BindingContext,
val resolutionFacade: ResolutionFacade, val resolutionFacade: ResolutionFacade,
val moduleDescriptor: ModuleDescriptor,
val useHeuristicSignatures: Boolean = true, val useHeuristicSignatures: Boolean = true,
val useOuterCallsExpectedTypeCount: Int = 0 val useOuterCallsExpectedTypeCount: Int = 0
) { ) {
@@ -203,7 +201,7 @@ class ExpectedInfos(
if (useOuterCallsExpectedTypeCount > 0 && results.any(::makesSenseToUseOuterCallExpectedType)) { if (useOuterCallsExpectedTypeCount > 0 && results.any(::makesSenseToUseOuterCallExpectedType)) {
val callExpression = (call.callElement as? JetExpression)?.getQualifiedExpressionForSelectorOrThis() ?: return results val callExpression = (call.callElement as? JetExpression)?.getQualifiedExpressionForSelectorOrThis() ?: return results
val expectedFuzzyTypes = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useHeuristicSignatures, useOuterCallsExpectedTypeCount - 1) val expectedFuzzyTypes = ExpectedInfos(bindingContext, resolutionFacade, useHeuristicSignatures, useOuterCallsExpectedTypeCount - 1)
.calculate(callExpression) .calculate(callExpression)
.map { it.fuzzyType } .map { it.fuzzyType }
.filterNotNull() .filterNotNull()
@@ -228,9 +226,6 @@ class ExpectedInfos(
val isFunctionLiteralArgument = argument is FunctionLiteralArgument val isFunctionLiteralArgument = argument is FunctionLiteralArgument
val argumentPosition = ArgumentPosition(argumentIndex, argumentName, isFunctionLiteralArgument) val argumentPosition = ArgumentPosition(argumentIndex, argumentName, isFunctionLiteralArgument)
val project = call.callElement.getProject()
val moduleDescriptor = resolutionFacade.findModuleDescriptor(call.callElement)
// leave only arguments before the current one // leave only arguments before the current one
val truncatedCall = object : DelegatingCall(call) { val truncatedCall = object : DelegatingCall(call) {
val arguments = call.getValueArguments().subList(0, argumentIndex) val arguments = call.getValueArguments().subList(0, argumentIndex)
@@ -247,7 +242,7 @@ class ExpectedInfos(
ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
CallChecker.DoNothing, false) CallChecker.DoNothing, false)
val callResolutionContext = context.replaceCollectAllCandidates(true) val callResolutionContext = context.replaceCollectAllCandidates(true)
val callResolver = resolutionFacade.frontendService<CallResolver>(moduleDescriptor) val callResolver = resolutionFacade.frontendService<CallResolver>()
val results: OverloadResolutionResults<FunctionDescriptor> = callResolver.resolveFunctionCall(callResolutionContext) val results: OverloadResolutionResults<FunctionDescriptor> = callResolver.resolveFunctionCall(callResolutionContext)
val expectedInfos = LinkedHashSet<ExpectedInfo>() val expectedInfos = LinkedHashSet<ExpectedInfo>()
@@ -320,7 +315,7 @@ class ExpectedInfos(
if (alreadyHasStar) continue if (alreadyHasStar) continue
val parameterType = if (useHeuristicSignatures) val parameterType = if (useHeuristicSignatures)
resolutionFacade.ideService<HeuristicSignatures>(moduleDescriptor). resolutionFacade.ideService<HeuristicSignatures>().
correctedParameterType(descriptor, parameter) ?: parameter.getType() correctedParameterType(descriptor, parameter) ?: parameter.getType()
else else
parameter.getType() parameter.getType()
@@ -509,7 +504,7 @@ class ExpectedInfos(
null null
val scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, expressionWithType)!! val scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, expressionWithType)!!
val iterableDetector = resolutionFacade.ideService<IterableTypesDetection>(forExpression).createDetector(scope) val iterableDetector = resolutionFacade.ideService<IterableTypesDetection>().createDetector(scope)
val byTypeFilter = object : ByTypeFilter { val byTypeFilter = object : ByTypeFilter {
override fun matchingSubstitutor(descriptorType: FuzzyType): TypeSubstitutor? { override fun matchingSubstitutor(descriptorType: FuzzyType): TypeSubstitutor? {
@@ -526,7 +521,7 @@ class ExpectedInfos(
val leftOperandType = binaryExpression.left?.let { bindingContext.getType(it) } ?: return null val leftOperandType = binaryExpression.left?.let { bindingContext.getType(it) } ?: return null
val scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, expressionWithType)!! val scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, expressionWithType)!!
val detector = TypesWithContainsDetector(scope, leftOperandType, resolutionFacade.ideService<HeuristicSignatures>(binaryExpression)) val detector = TypesWithContainsDetector(scope, leftOperandType, resolutionFacade.ideService<HeuristicSignatures>())
val byTypeFilter = object : ByTypeFilter { val byTypeFilter = object : ByTypeFilter {
override fun matchingSubstitutor(descriptorType: FuzzyType): TypeSubstitutor? { override fun matchingSubstitutor(descriptorType: FuzzyType): TypeSubstitutor? {
@@ -78,8 +78,8 @@ private fun needExplicitParameterTypes(context: InsertionContext, placeholderRan
val resolutionFacade = file.getResolutionFacade() val resolutionFacade = file.getResolutionFacade()
val bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.PARTIAL) val bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.PARTIAL)
val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, resolutionFacade.findModuleDescriptor(file), useHeuristicSignatures = false) val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, useHeuristicSignatures = false).calculate(expression)
.calculate(expression)
val functionTypes = expectedInfos val functionTypes = expectedInfos
.map { it.fuzzyType?.type } .map { it.fuzzyType?.type }
.filterNotNull() .filterNotNull()
@@ -51,7 +51,6 @@ interface InheritanceItemsSearcher {
class SmartCompletion( class SmartCompletion(
private val expression: JetExpression, private val expression: JetExpression,
private val resolutionFacade: ResolutionFacade, private val resolutionFacade: ResolutionFacade,
private val moduleDescriptor: ModuleDescriptor,
private val bindingContext: BindingContext, private val bindingContext: BindingContext,
private val visibilityFilter: (DeclarationDescriptor) -> Boolean, private val visibilityFilter: (DeclarationDescriptor) -> Boolean,
private val inDescriptor: DeclarationDescriptor, private val inDescriptor: DeclarationDescriptor,
@@ -66,7 +65,9 @@ class SmartCompletion(
public val expectedInfos: Collection<ExpectedInfo> = calcExpectedInfos(expressionWithType) public val expectedInfos: Collection<ExpectedInfo> = calcExpectedInfos(expressionWithType)
public val smartCastCalculator: SmartCastCalculator by lazy { SmartCastCalculator(bindingContext, moduleDescriptor, expression) } public val smartCastCalculator: SmartCastCalculator by lazy {
SmartCastCalculator(bindingContext, resolutionFacade.moduleDescriptor, expression)
}
public val descriptorFilter: ((DeclarationDescriptor) -> Collection<LookupElement>)? public val descriptorFilter: ((DeclarationDescriptor) -> Collection<LookupElement>)?
= { descriptor: DeclarationDescriptor -> filterDescriptor(descriptor).map { postProcess(it) } }.check { expectedInfos.isNotEmpty() } = { descriptor: DeclarationDescriptor -> filterDescriptor(descriptor).map { postProcess(it) } }.check { expectedInfos.isNotEmpty() }
@@ -172,7 +173,7 @@ class SmartCompletion(
val inheritanceSearchers = ArrayList<InheritanceItemsSearcher>() val inheritanceSearchers = ArrayList<InheritanceItemsSearcher>()
if (expectedInfos.isNotEmpty() && receiver == null) { if (expectedInfos.isNotEmpty() && receiver == null) {
TypeInstantiationItems(resolutionFacade, moduleDescriptor, bindingContext, visibilityFilter, toFromOriginalFileMapper, inheritorSearchScope, lookupElementFactory, forBasicCompletion) TypeInstantiationItems(resolutionFacade, bindingContext, visibilityFilter, toFromOriginalFileMapper, inheritorSearchScope, lookupElementFactory, forBasicCompletion)
.addTo(items, inheritanceSearchers, expectedInfos) .addTo(items, inheritanceSearchers, expectedInfos)
if (expression is JetSimpleNameExpression) { if (expression is JetSimpleNameExpression) {
@@ -254,7 +255,7 @@ class SmartCompletion(
// if expected types are too general, try to use expected type from outer calls // if expected types are too general, try to use expected type from outer calls
var count = 0 var count = 0
while (true) { while (true) {
val infos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useOuterCallsExpectedTypeCount = count) val infos = ExpectedInfos(bindingContext, resolutionFacade, useOuterCallsExpectedTypeCount = count)
.calculate(expression) .calculate(expression)
if (count == 2 /* use two outer calls maximum */ || infos.none { it.fuzzyType?.isAlmostEverything() ?: false }) { if (count == 2 /* use two outer calls maximum */ || infos.none { it.fuzzyType?.isAlmostEverything() ?: false }) {
return if (forBasicCompletion) return if (forBasicCompletion)
@@ -47,9 +47,10 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
if (expression != null) { if (expression != null) {
addFunctionLiteralArgumentCompletions() addFunctionLiteralArgumentCompletions()
val completion = SmartCompletion(expression, resolutionFacade, moduleDescriptor, val completion = SmartCompletion(
bindingContext, isVisibleFilter, inDescriptor, prefixMatcher, originalSearchScope, expression, resolutionFacade, bindingContext, isVisibleFilter, inDescriptor,
toFromOriginalFileMapper, lookupElementFactory) prefixMatcher, originalSearchScope, toFromOriginalFileMapper, lookupElementFactory
)
val (additionalItems, inheritanceSearcher) = completion.additionalItems() val (additionalItems, inheritanceSearcher) = completion.additionalItems()
collector.addElements(additionalItems) collector.addElements(additionalItems)
@@ -103,7 +104,7 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
override fun getValueArgumentList() = throw UnsupportedOperationException() override fun getValueArgumentList() = throw UnsupportedOperationException()
} }
val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor) val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade)
.calculateForArgument(dummyCall, dummyArgument) .calculateForArgument(dummyCall, dummyArgument)
collector.addElements(LambdaItems.collect(expectedInfos)) collector.addElements(LambdaItems.collect(expectedInfos))
} }
@@ -28,12 +28,12 @@ import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.completion.* import org.jetbrains.kotlin.idea.completion.*
import org.jetbrains.kotlin.idea.completion.handlers.CaretPosition import org.jetbrains.kotlin.idea.completion.handlers.CaretPosition
import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMethodsHandler import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMethodsHandler
import org.jetbrains.kotlin.idea.core.psiClassToDescriptor import org.jetbrains.kotlin.idea.core.psiClassToDescriptor
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor
@@ -53,7 +53,6 @@ import org.jetbrains.kotlin.utils.addIfNotNull
class TypeInstantiationItems( class TypeInstantiationItems(
val resolutionFacade: ResolutionFacade, val resolutionFacade: ResolutionFacade,
val moduleDescriptor: ModuleDescriptor,
val bindingContext: BindingContext, val bindingContext: BindingContext,
val visibilityFilter: (DeclarationDescriptor) -> Boolean, val visibilityFilter: (DeclarationDescriptor) -> Boolean,
val toFromOriginalFileMapper: ToFromOriginalFileMapper, val toFromOriginalFileMapper: ToFromOriginalFileMapper,
@@ -95,7 +94,7 @@ class TypeInstantiationItems(
val javaClassId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(DescriptorUtils.getFqName(classifier)) val javaClassId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(DescriptorUtils.getFqName(classifier))
if (javaClassId != null) { if (javaClassId != null) {
val javaAnalog = moduleDescriptor.resolveTopLevelClass(javaClassId.asSingleFqName()) val javaAnalog = resolutionFacade.moduleDescriptor.resolveTopLevelClass(javaClassId.asSingleFqName())
if (javaAnalog != null) { if (javaAnalog != null) {
inheritanceSearchers.addInheritorSearcher(javaAnalog, classifier, typeArgs, tail) inheritanceSearchers.addInheritorSearcher(javaAnalog, classifier, typeArgs, tail)
} }
@@ -17,16 +17,15 @@
package org.jetbrains.kotlin.idea.core package org.jetbrains.kotlin.idea.core
import com.intellij.codeInsight.CodeInsightSettings import com.intellij.codeInsight.CodeInsightSettings
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.PsiShortNamesCache import com.intellij.psi.search.PsiShortNamesCache
import com.intellij.psi.stubs.StringStubIndexExtension import com.intellij.psi.stubs.StringStubIndexExtension
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper
import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.stubindex.* import org.jetbrains.kotlin.idea.stubindex.*
import org.jetbrains.kotlin.idea.util.CallType import org.jetbrains.kotlin.idea.util.CallType
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance
@@ -50,13 +49,15 @@ import java.util.HashSet
import java.util.LinkedHashSet import java.util.LinkedHashSet
public class KotlinIndicesHelper( public class KotlinIndicesHelper(
private val project: Project,
private val resolutionFacade: ResolutionFacade, private val resolutionFacade: ResolutionFacade,
private val scope: GlobalSearchScope, private val scope: GlobalSearchScope,
private val moduleDescriptor: ModuleDescriptor,
visibilityFilter: (DeclarationDescriptor) -> Boolean, visibilityFilter: (DeclarationDescriptor) -> Boolean,
applyExcludeSettings: Boolean applyExcludeSettings: Boolean
) { ) {
private val moduleDescriptor = resolutionFacade.moduleDescriptor
private val project = resolutionFacade.project
private val descriptorFilter = private val descriptorFilter =
if (applyExcludeSettings) if (applyExcludeSettings)
{ d -> visibilityFilter(d) && !isExcludedFromAutoImport(d) } { d -> visibilityFilter(d) && !isExcludedFromAutoImport(d) }
@@ -69,7 +70,7 @@ public class KotlinIndicesHelper(
declarations.addTopLevelNonExtensionCallablesByName(JetPropertyShortNameIndex.getInstance(), name) declarations.addTopLevelNonExtensionCallablesByName(JetPropertyShortNameIndex.getInstance(), name)
return declarations.flatMap { return declarations.flatMap {
if (it.getContainingJetFile().isCompiled()) { //TODO: it's temporary while resolveToDescriptor does not work for compiled declarations if (it.getContainingJetFile().isCompiled()) { //TODO: it's temporary while resolveToDescriptor does not work for compiled declarations
resolutionFacade.resolveImportReference(project, moduleDescriptor, it.getFqName()!!).filterIsInstance<CallableDescriptor>() resolutionFacade.resolveImportReference(moduleDescriptor, it.getFqName()!!).filterIsInstance<CallableDescriptor>()
} }
else { else {
(resolutionFacade.resolveToDescriptor(it) as? CallableDescriptor).singletonOrEmptyList() (resolutionFacade.resolveToDescriptor(it) as? CallableDescriptor).singletonOrEmptyList()
@@ -117,7 +118,7 @@ public class KotlinIndicesHelper(
private fun possibleReceiverTypeNames(receiverValues: Collection<ReceiverValue>, dataFlowInfo: DataFlowInfo, bindingContext: BindingContext): Set<String> { private fun possibleReceiverTypeNames(receiverValues: Collection<ReceiverValue>, dataFlowInfo: DataFlowInfo, bindingContext: BindingContext): Set<String> {
val result = HashSet<String>() val result = HashSet<String>()
for (receiverValue in receiverValues) { for (receiverValue in receiverValues) {
val smartCastManager = resolutionFacade.frontendService<SmartCastManager>(moduleDescriptor) val smartCastManager = resolutionFacade.frontendService<SmartCastManager>()
for (type in smartCastManager.getSmartCastVariants(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)) { for (type in smartCastManager.getSmartCastVariants(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)) {
result.addTypeNames(type) result.addTypeNames(type)
} }
@@ -171,7 +172,7 @@ public class KotlinIndicesHelper(
for (declaration in declarations) { for (declaration in declarations) {
if (declaration.getContainingJetFile().isCompiled()) { if (declaration.getContainingJetFile().isCompiled()) {
//TODO: it's temporary while resolveToDescriptor does not work for compiled declarations //TODO: it's temporary while resolveToDescriptor does not work for compiled declarations
for (descriptor in resolutionFacade.resolveImportReference(project, moduleDescriptor, declaration.getFqName()!!)) { for (descriptor in resolutionFacade.resolveImportReference(moduleDescriptor, declaration.getFqName()!!)) {
if (descriptor is CallableDescriptor && descriptor.getExtensionReceiverParameter() != null) { if (descriptor is CallableDescriptor && descriptor.getExtensionReceiverParameter() != null) {
processDescriptor(descriptor) processDescriptor(descriptor)
} }
@@ -214,7 +215,7 @@ public class KotlinIndicesHelper(
} }
private fun findTopLevelCallables(fqName: FqName): Collection<CallableDescriptor> { private fun findTopLevelCallables(fqName: FqName): Collection<CallableDescriptor> {
return resolutionFacade.resolveImportReference(project, moduleDescriptor, fqName) return resolutionFacade.resolveImportReference(moduleDescriptor, fqName)
.filterIsInstance<CallableDescriptor>() .filterIsInstance<CallableDescriptor>()
.filter { it.getExtensionReceiverParameter() == null } .filter { it.getExtensionReceiverParameter() == null }
} }
@@ -36,6 +36,6 @@ public fun ResolutionFacade.psiClassToDescriptor(
resolveToDescriptor(declaration) resolveToDescriptor(declaration)
} }
else { else {
frontendService<JavaDescriptorResolver>(psiClass).resolveClass(JavaClassImpl(psiClass)) this.getFrontendService(psiClass, javaClass<JavaDescriptorResolver>()).resolveClass(JavaClassImpl(psiClass))
} as? ClassifierDescriptor } as? ClassifierDescriptor
} }
@@ -22,11 +22,11 @@ import com.intellij.codeInsight.template.impl.ConstantNode
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.resolve.ideService
import org.jetbrains.kotlin.idea.core.IterableTypesDetection import org.jetbrains.kotlin.idea.core.IterableTypesDetection
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.resolve.ideService
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.siblings import org.jetbrains.kotlin.psi.psiUtil.siblings
@@ -51,7 +51,7 @@ public class IterateExpressionIntention : JetSelfTargetingIntention<JetExpressio
val bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.PARTIAL) val bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.PARTIAL)
val type = bindingContext.getType(expression) ?: return null val type = bindingContext.getType(expression) ?: return null
val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, expression] ?: return null val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, expression] ?: return null
val detector = resolutionFacade.ideService<IterableTypesDetection>(expression).createDetector(scope) val detector = resolutionFacade.ideService<IterableTypesDetection>().createDetector(scope)
val elementType = detector.elementType(type)?.type ?: return null val elementType = detector.elementType(type)?.type ?: return null
return Data(type, elementType) return Data(type, elementType)
} }
@@ -69,7 +69,7 @@ public class RemoveExplicitTypeArgumentsIntention : JetSelfTargetingOffsetIndepe
TypeUtils.NO_EXPECTED_TYPE TypeUtils.NO_EXPECTED_TYPE
} }
val dataFlow = context.getDataFlowInfo(callExpression) val dataFlow = context.getDataFlowInfo(callExpression)
val callResolver = resolutionFacade.frontendService<CallResolver>(callExpression) val callResolver = resolutionFacade.frontendService<CallResolver>()
val resolutionResults = callResolver.resolveFunctionCall( val resolutionResults = callResolver.resolveFunctionCall(
BindingTraceContext(), scope, untypedCall, expectedType, dataFlow, false) BindingTraceContext(), scope, untypedCall, expectedType, dataFlow, false)
if (!resolutionResults.isSingleResult()) { if (!resolutionResults.isSingleResult()) {
@@ -89,7 +89,7 @@ class UsePropertyAccessSyntaxIntention : JetSelfTargetingOffsetIndependentIntent
val qualifiedExpression = callExpression.getQualifiedExpressionForSelectorOrThis() val qualifiedExpression = callExpression.getQualifiedExpressionForSelectorOrThis()
val expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, qualifiedExpression] ?: TypeUtils.NO_EXPECTED_TYPE val expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, qualifiedExpression] ?: TypeUtils.NO_EXPECTED_TYPE
if (!checkWillResolveToProperty(resolvedCall, property, bindingContext, resolutionScope, dataFlowInfo, expectedType, resolutionFacade, callExpression)) return null if (!checkWillResolveToProperty(resolvedCall, property, bindingContext, resolutionScope, dataFlowInfo, expectedType, resolutionFacade)) return null
val isSetUsage = callExpression.valueArguments.size() == 1 val isSetUsage = callExpression.valueArguments.size() == 1
if (isSetUsage && property.type != function.valueParameters.single().type) { if (isSetUsage && property.type != function.valueParameters.single().type) {
@@ -118,8 +118,7 @@ class UsePropertyAccessSyntaxIntention : JetSelfTargetingOffsetIndependentIntent
resolutionScope: JetScope, resolutionScope: JetScope,
dataFlowInfo: DataFlowInfo, dataFlowInfo: DataFlowInfo,
expectedType: JetType, expectedType: JetType,
facade: ResolutionFacade, facade: ResolutionFacade
callExpression: JetCallExpression
): Boolean { ): Boolean {
val project = resolvedCall.call.callElement.project val project = resolvedCall.call.callElement.project
val newCall = object : DelegatingCall(resolvedCall.call) { val newCall = object : DelegatingCall(resolvedCall.call) {
@@ -135,7 +134,7 @@ class UsePropertyAccessSyntaxIntention : JetSelfTargetingOffsetIndependentIntent
val context = BasicCallResolutionContext.create(bindingTrace, resolutionScope, newCall, expectedType, dataFlowInfo, val context = BasicCallResolutionContext.create(bindingTrace, resolutionScope, newCall, expectedType, dataFlowInfo,
ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
CallChecker.DoNothing, false) CallChecker.DoNothing, false)
val callResolver = facade.frontendService<CallResolver>(callExpression) val callResolver = facade.frontendService<CallResolver>()
val result = callResolver.resolveSimpleProperty(context) val result = callResolver.resolveSimpleProperty(context)
return result.isSuccess && result.resultingDescriptor.original == property return result.isSuccess && result.resultingDescriptor.original == property
} }
@@ -233,10 +233,8 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
} }
}; };
ModuleDescriptor moduleDescriptor = resolutionFacade.findModuleDescriptor(jetFile);
state = new GenerationState(jetFile.getProject(), ClassBuilderFactories.TEST, Progress.DEAF, state = new GenerationState(jetFile.getProject(), ClassBuilderFactories.TEST, Progress.DEAF,
moduleDescriptor, bindingContext, resolutionFacade.getModuleDescriptor(), bindingContext,
toProcess, !enableAssertions, !enableAssertions, toProcess, !enableAssertions, !enableAssertions,
generateClassFilter, generateClassFilter,
!enableInline, !enableOptimization, null, null, !enableInline, !enableOptimization, null, null,
@@ -72,8 +72,7 @@ public abstract class BaseJetVariableMacro extends Macro {
return null; return null;
} }
IterableTypesDetector detector = IterableTypesDetector detector = resolutionFacade.getIdeService(IterableTypesDetection.class).createDetector(scope);
resolutionFacade.getIdeService(contextExpression, IterableTypesDetection.class).createDetector(scope);
DataFlowInfo dataFlowInfo = getDataFlowInfo(bindingContext, contextExpression); DataFlowInfo dataFlowInfo = getDataFlowInfo(bindingContext, contextExpression);
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.JetBundle import org.jetbrains.kotlin.idea.JetBundle
import org.jetbrains.kotlin.idea.actions.JetAddImportAction import org.jetbrains.kotlin.idea.actions.JetAddImportAction
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.getResolveScope import org.jetbrains.kotlin.idea.caches.resolve.getResolveScope
import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
@@ -135,8 +134,7 @@ public class AutoImportFix(element: JetSimpleNameExpression) : JetHintAction<Jet
val result = ArrayList<DeclarationDescriptor>() val result = ArrayList<DeclarationDescriptor>()
val moduleDescriptor = resolutionFacade.findModuleDescriptor(element) val indicesHelper = KotlinIndicesHelper(resolutionFacade, searchScope, ::isVisible, true)
val indicesHelper = KotlinIndicesHelper(file.getProject(), resolutionFacade, searchScope, moduleDescriptor, ::isVisible, true)
if (!element.isImportDirectiveExpression() && !JetPsiUtil.isSelectorInQualified(element)) { if (!element.isImportDirectiveExpression() && !JetPsiUtil.isSelectorInQualified(element)) {
if (ProjectStructureUtil.isJsKotlinModule(file)) { if (ProjectStructureUtil.isJsKotlinModule(file)) {
@@ -91,7 +91,7 @@ public abstract class DeprecatedSymbolUsageFixBase(
val resolvedCall = element.getResolvedCall(bindingContext)!! val resolvedCall = element.getResolvedCall(bindingContext)!!
val descriptor = resolvedCall.getResultingDescriptor() val descriptor = resolvedCall.getResultingDescriptor()
val replacement = ReplaceWithAnnotationAnalyzer.analyze(replaceWith, descriptor, element.getResolutionFacade(), project) val replacement = ReplaceWithAnnotationAnalyzer.analyze(replaceWith, descriptor, element.getResolutionFacade())
invoke(resolvedCall, bindingContext, replacement, project, editor) invoke(resolvedCall, bindingContext, replacement, project, editor)
} }
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.quickfix package org.jetbrains.kotlin.idea.quickfix
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
@@ -29,7 +28,6 @@ import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport
import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.intentions.InsertExplicitTypeArgumentsIntention import org.jetbrains.kotlin.idea.intentions.InsertExplicitTypeArgumentsIntention
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -67,23 +65,21 @@ object ReplaceWithAnnotationAnalyzer {
public fun analyze( public fun analyze(
annotation: ReplaceWith, annotation: ReplaceWith,
symbolDescriptor: CallableDescriptor, symbolDescriptor: CallableDescriptor,
resolutionFacade: ResolutionFacade, resolutionFacade: ResolutionFacade
project: Project
): ReplacementExpression { ): ReplacementExpression {
val originalDescriptor = (if (symbolDescriptor is CallableMemberDescriptor) val originalDescriptor = (if (symbolDescriptor is CallableMemberDescriptor)
DescriptorUtils.unwrapFakeOverride(symbolDescriptor) DescriptorUtils.unwrapFakeOverride(symbolDescriptor)
else else
symbolDescriptor).getOriginal() symbolDescriptor).getOriginal()
return analyzeOriginal(annotation, originalDescriptor, resolutionFacade, project) return analyzeOriginal(annotation, originalDescriptor, resolutionFacade)
} }
private fun analyzeOriginal( private fun analyzeOriginal(
annotation: ReplaceWith, annotation: ReplaceWith,
symbolDescriptor: CallableDescriptor, symbolDescriptor: CallableDescriptor,
resolutionFacade: ResolutionFacade, resolutionFacade: ResolutionFacade
project: Project
): ReplacementExpression { ): ReplacementExpression {
val psiFactory = JetPsiFactory(project) val psiFactory = JetPsiFactory(resolutionFacade.project)
var expression = psiFactory.createExpression(annotation.expression) var expression = psiFactory.createExpression(annotation.expression)
val importFqNames = annotation.imports val importFqNames = annotation.imports
@@ -92,7 +88,7 @@ object ReplaceWithAnnotationAnalyzer {
.filter { it.isSafe() } .filter { it.isSafe() }
.mapTo(LinkedHashSet<FqName>()) { it.toSafe() } .mapTo(LinkedHashSet<FqName>()) { it.toSafe() }
val explicitlyImportedSymbols = importFqNames.flatMap { resolutionFacade.resolveImportReference(project, symbolDescriptor.module, it) } val explicitlyImportedSymbols = importFqNames.flatMap { resolutionFacade.resolveImportReference(symbolDescriptor.module, it) }
val symbolScope = getResolutionScope(symbolDescriptor) val symbolScope = getResolutionScope(symbolDescriptor)
val scope = ChainedScope(symbolDescriptor, "ReplaceWith resolution scope", ExplicitImportsScope(explicitlyImportedSymbols), symbolScope) val scope = ChainedScope(symbolDescriptor, "ReplaceWith resolution scope", ExplicitImportsScope(explicitlyImportedSymbols), symbolScope)
@@ -167,7 +163,7 @@ object ReplaceWithAnnotationAnalyzer {
resolutionFacade: ResolutionFacade resolutionFacade: ResolutionFacade
): BindingContext { ): BindingContext {
val traceContext = BindingTraceContext() val traceContext = BindingTraceContext()
resolutionFacade.frontendService<ExpressionTypingServices>(symbolDescriptor.module) resolutionFacade.getFrontendService(symbolDescriptor.module, javaClass<ExpressionTypingServices>())
.getTypeInfo(scope, expression, TypeUtils.NO_EXPECTED_TYPE, DataFlowInfo.EMPTY, traceContext, false) .getTypeInfo(scope, expression, TypeUtils.NO_EXPECTED_TYPE, DataFlowInfo.EMPTY, traceContext, false)
return traceContext.bindingContext return traceContext.bindingContext
} }
@@ -204,7 +204,7 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert
val targetFqName = target.importableFqNameSafe val targetFqName = target.importableFqNameSafe
val parentFqName = targetFqName.parent() val parentFqName = targetFqName.parent()
val moduleDescriptor = resolutionFacade.findModuleDescriptor(file) val moduleDescriptor = resolutionFacade.moduleDescriptor
val imports = file.getImportDirectives() val imports = file.getImportDirectives()
val scopeToImport = getMemberScope(parentFqName, moduleDescriptor) ?: return ImportDescriptorResult.FAIL val scopeToImport = getMemberScope(parentFqName, moduleDescriptor) ?: return ImportDescriptorResult.FAIL
val importedScopes = imports val importedScopes = imports