KotlinCacheService: allow to get ResolveSessionForBodies by module descriptor

Utility to resolve import in file by fq name
This commit is contained in:
Pavel V. Talanov
2015-06-01 18:47:59 +03:00
parent e60c3f5ee7
commit a94c13be6d
14 changed files with 61 additions and 51 deletions
@@ -36,13 +36,15 @@ public trait ResolverForModule {
} }
public trait ResolverForProject<M : ModuleInfo,out R : ResolverForModule> { public trait ResolverForProject<M : ModuleInfo,out R : ResolverForModule> {
public fun resolverForModule(moduleInfo: M): R public fun resolverForModule(moduleInfo: M): R = resolverForModuleDescriptor(descriptorForModule(moduleInfo))
public fun descriptorForModule(moduleInfo: M): ModuleDescriptor public fun descriptorForModule(moduleInfo: M): ModuleDescriptor
public fun resolverForModuleDescriptor(descriptor: ModuleDescriptor): R
val allModules: Collection<M> val allModules: Collection<M>
} }
public class EmptyResolverForProject<M : ModuleInfo, R : ResolverForModule> : ResolverForProject<M, R> { public class EmptyResolverForProject<M : ModuleInfo, R : ResolverForModule> : ResolverForProject<M, R> {
override fun resolverForModule(moduleInfo: M): R = throw IllegalStateException("Should not be called for $moduleInfo") override fun resolverForModuleDescriptor(descriptor: ModuleDescriptor): R = throw IllegalStateException("$descriptor is not contained in this resolver")
override fun descriptorForModule(moduleInfo: M) = throw IllegalStateException("Should not be called for $moduleInfo") override fun descriptorForModule(moduleInfo: M) = throw IllegalStateException("Should not be called for $moduleInfo")
override val allModules: Collection<M> = listOf() override val allModules: Collection<M> = listOf()
} }
@@ -63,10 +65,8 @@ public class ResolverForProjectImpl<M : ModuleInfo, R : ResolverForModule>(
} }
} }
override fun resolverForModule(moduleInfo: M): R { override fun resolverForModuleDescriptor(descriptor: ModuleDescriptor): R {
assertCorrectModuleInfo(moduleInfo) return resolverByModuleDescriptor[descriptor] ?: return delegateResolver.resolverForModuleDescriptor(descriptor)
val descriptor = descriptorByModule[moduleInfo] ?: return delegateResolver.resolverForModule(moduleInfo)
return resolverByModuleDescriptor[descriptor]!!
} }
override fun descriptorForModule(moduleInfo: M): ModuleDescriptorImpl { override fun descriptorForModule(moduleInfo: M): ModuleDescriptorImpl {
@@ -71,10 +71,9 @@ public class KotlinCacheService(val project: Project) {
return cache.getLazyResolveSession(file).getScopeProvider().getFileScope(file) return cache.getLazyResolveSession(file).getScopeProvider().getFileScope(file)
} }
override fun resolveImportReference(file: JetFile, fqName: FqName, isDefaultImport: Boolean): Collection<DeclarationDescriptor> { override fun resolveImportReference(moduleDescriptor: ModuleDescriptor, fqName: FqName, isDefaultImport: Boolean): Collection<DeclarationDescriptor> {
val importDirective = JetPsiFactory(project).createImportDirective(ImportPath(fqName, false)) val importDirective = JetPsiFactory(project).createImportDirective(ImportPath(fqName, false))
val moduleDescriptor = findModuleDescriptor(file) val resolveSession = cache.getLazyResolveSession(moduleDescriptor)
val resolveSession = cache.getLazyResolveSession(file)
val scope = JetModuleUtil.getImportsResolutionScope(moduleDescriptor, !isDefaultImport) val scope = JetModuleUtil.getImportsResolutionScope(moduleDescriptor, !isDefaultImport)
val resolver = resolveSession.getQualifiedExpressionResolver() val resolver = resolveSession.getQualifiedExpressionResolver()
return resolver.processImportReference( return resolver.processImportReference(
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.context.SimpleGlobalContext import org.jetbrains.kotlin.context.SimpleGlobalContext
import org.jetbrains.kotlin.context.withModule import org.jetbrains.kotlin.context.withModule
import org.jetbrains.kotlin.context.withProject import org.jetbrains.kotlin.context.withProject
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.di.InjectorForLazyBodyResolve import org.jetbrains.kotlin.di.InjectorForLazyBodyResolve
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.idea.project.ResolveSessionForBodies import org.jetbrains.kotlin.idea.project.ResolveSessionForBodies
@@ -67,6 +68,10 @@ private class KotlinResolveCache(
return moduleResolverProvider.resolveSessionForBodiesByModule(element.getModuleInfo()) return moduleResolverProvider.resolveSessionForBodiesByModule(element.getModuleInfo())
} }
public fun getLazyResolveSession(moduleDescriptor: ModuleDescriptor): ResolveSessionForBodies {
return moduleResolverProvider.resolveSessionForBodiesByDescriptor(moduleDescriptor)
}
public fun <T> get(extension: CacheExtension<T>): T { public fun <T> get(extension: CacheExtension<T>): T {
return extension.getData(moduleResolverProvider) return extension.getData(moduleResolverProvider)
} }
@@ -24,6 +24,7 @@ import com.intellij.openapi.roots.ModuleRootManager
import org.jetbrains.kotlin.analyzer.* import org.jetbrains.kotlin.analyzer.*
import org.jetbrains.kotlin.context.GlobalContextImpl import org.jetbrains.kotlin.context.GlobalContextImpl
import org.jetbrains.kotlin.context.withProject import org.jetbrains.kotlin.context.withProject
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.project.ResolveSessionForBodies import org.jetbrains.kotlin.idea.project.ResolveSessionForBodies
import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
@@ -69,14 +70,15 @@ fun createModuleResolverProvider(
val resolverForProject = createResolverForProject() val resolverForProject = createResolverForProject()
val moduleToBodiesResolveSession = modulesToCreateResolversFor.keysToMap { val moduleDescriptors = modulesToCreateResolversFor.map { resolverForProject.descriptorForModule(it) }
module -> val resolveSessionsForBodyByDescriptor = moduleDescriptors.keysToMap {
val analyzer = resolverForProject.resolverForModule(module) descriptor ->
val analyzer = resolverForProject.resolverForModuleDescriptor(descriptor)
ResolveSessionForBodies(project, analyzer.lazyResolveSession) ResolveSessionForBodies(project, analyzer.lazyResolveSession)
} }
return ModuleResolverProviderImpl( return ModuleResolverProviderImpl(
resolverForProject, resolverForProject,
moduleToBodiesResolveSession, resolveSessionsForBodyByDescriptor,
globalContext, globalContext,
delegateProvider delegateProvider
) )
@@ -110,7 +112,12 @@ private fun collectAllModuleInfosFromIdeaModel(project: Project): List<IdeaModul
trait ModuleResolverProvider { trait ModuleResolverProvider {
val exceptionTracker: ExceptionTracker val exceptionTracker: ExceptionTracker
fun resolverByModule(module: IdeaModuleInfo): ResolverForModule = resolverForProject.resolverForModule(module) fun resolverByModule(module: IdeaModuleInfo): ResolverForModule = resolverForProject.resolverForModule(module)
fun resolveSessionForBodiesByModule(module: IdeaModuleInfo): ResolveSessionForBodies
fun resolveSessionForBodiesByModule(module: IdeaModuleInfo): ResolveSessionForBodies {
return resolveSessionForBodiesByDescriptor(resolverForProject.descriptorForModule(module))
}
fun resolveSessionForBodiesByDescriptor(descriptor: ModuleDescriptor): ResolveSessionForBodies
val resolverForProject: ResolverForProject<IdeaModuleInfo, ResolverForModule> val resolverForProject: ResolverForProject<IdeaModuleInfo, ResolverForModule>
} }
@@ -118,22 +125,23 @@ object EmptyModuleResolverProvider: ModuleResolverProvider {
override val exceptionTracker: ExceptionTracker override val exceptionTracker: ExceptionTracker
get() = throw IllegalStateException("Should not be called") get() = throw IllegalStateException("Should not be called")
override fun resolveSessionForBodiesByModule(module: IdeaModuleInfo): ResolveSessionForBodies
= throw IllegalStateException("Trying to obtain resolve session for unknown $module")
override val resolverForProject: ResolverForProject<IdeaModuleInfo, ResolverForModule> = EmptyResolverForProject() override val resolverForProject: ResolverForProject<IdeaModuleInfo, ResolverForModule> = EmptyResolverForProject()
override fun resolveSessionForBodiesByDescriptor(descriptor: ModuleDescriptor): ResolveSessionForBodies {
throw IllegalStateException("Trying to obtain resolve session for $descriptor not present in this resolver")
}
} }
class ModuleResolverProviderImpl( class ModuleResolverProviderImpl(
override val resolverForProject: ResolverForProject<IdeaModuleInfo, ResolverForModule>, override val resolverForProject: ResolverForProject<IdeaModuleInfo, ResolverForModule>,
private val bodiesResolveByModule: Map<IdeaModuleInfo, ResolveSessionForBodies>, private val bodiesResolveByDescriptor: Map<ModuleDescriptor, ResolveSessionForBodies>,
val globalContext: GlobalContextImpl, val globalContext: GlobalContextImpl,
val delegateProvider: ModuleResolverProvider = EmptyModuleResolverProvider val delegateProvider: ModuleResolverProvider = EmptyModuleResolverProvider
): ModuleResolverProvider { ): ModuleResolverProvider {
override val exceptionTracker: ExceptionTracker = globalContext.exceptionTracker override val exceptionTracker: ExceptionTracker = globalContext.exceptionTracker
override fun resolveSessionForBodiesByModule(module: IdeaModuleInfo): ResolveSessionForBodies = override fun resolveSessionForBodiesByDescriptor(descriptor: ModuleDescriptor): ResolveSessionForBodies {
bodiesResolveByModule[module] ?: return bodiesResolveByDescriptor[descriptor] ?: delegateProvider.resolveSessionForBodiesByDescriptor(descriptor)
delegateProvider.resolveSessionForBodiesByModule(module) }
} }
@@ -37,8 +37,7 @@ public trait ResolutionFacade {
public fun getFileTopLevelScope(file: JetFile): JetScope public fun getFileTopLevelScope(file: JetFile): JetScope
//TODO: better pass ModuleDescriptor here public fun resolveImportReference(moduleDescriptor: ModuleDescriptor, fqName: FqName, isDefaultImport: Boolean = false): Collection<DeclarationDescriptor>
public fun resolveImportReference(file: JetFile, fqName: FqName, isDefaultImport: Boolean = false): Collection<DeclarationDescriptor>
public fun findModuleDescriptor(element: JetElement): ModuleDescriptor public fun findModuleDescriptor(element: JetElement): ModuleDescriptor
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.caches.resolve
import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.JetDeclaration import org.jetbrains.kotlin.psi.JetDeclaration
import org.jetbrains.kotlin.psi.JetElement import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetFile
@@ -33,6 +34,11 @@ public fun JetDeclaration.resolveToDescriptor(): DeclarationDescriptor {
return getResolutionFacade().resolveToDescriptor(this) return getResolutionFacade().resolveToDescriptor(this)
} }
public fun JetFile.resolveImportReference(fqName: FqName, isDefaultImport: Boolean = false): Collection<DeclarationDescriptor> {
val facade = getResolutionFacade()
return facade.resolveImportReference(facade.findModuleDescriptor(this), fqName, isDefaultImport)
}
//NOTE: the difference between analyze and analyzeFully is 'intentionally' unclear //NOTE: the difference between analyze and analyzeFully is 'intentionally' unclear
// in theory they do the same thing via different code // in theory they do the same thing via different code
// analyze - see ResolveSessionForBodies, ResolveElementCache // analyze - see ResolveSessionForBodies, ResolveElementCache
@@ -57,7 +57,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
analyzeImportReference(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()
@@ -158,7 +158,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 analyzeImportReference(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)
} }
@@ -194,16 +194,8 @@ public class KotlinIndicesHelper(
} }
private fun findTopLevelCallables(fqName: FqName): Collection<CallableDescriptor> { private fun findTopLevelCallables(fqName: FqName): Collection<CallableDescriptor> {
return analyzeImportReference(fqName) return resolutionFacade.resolveImportReference(moduleDescriptor, fqName)
.filterIsInstance<CallableDescriptor>() .filterIsInstance<CallableDescriptor>()
.filter { it.getExtensionReceiverParameter() == null } .filter { it.getExtensionReceiverParameter() == null }
} }
private fun analyzeImportReference(fqName: FqName): Collection<DeclarationDescriptor> {
val importDirective = JetPsiFactory(project).createImportDirective(ImportPath(fqName, false))
val scope = JetModuleUtil.getSubpackagesOfRootScope(moduleDescriptor)
val qualifiedExpressionResolver = QualifiedExpressionResolver()
qualifiedExpressionResolver.setSymbolUsageValidator(SymbolUsageValidator.Empty)
return qualifiedExpressionResolver.processImportReference(importDirective, scope, scope, BindingTraceContext(), LookupMode.EVERYTHING).getAllDescriptors()
}
} }
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedShortening import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedShortening
import org.jetbrains.kotlin.idea.conversion.copy.end import org.jetbrains.kotlin.idea.conversion.copy.end
import org.jetbrains.kotlin.idea.conversion.copy.range import org.jetbrains.kotlin.idea.conversion.copy.range
@@ -310,7 +311,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Kotlin
= this == KotlinReferenceData.Kind.EXTENSION_FUNCTION || this == KotlinReferenceData.Kind.EXTENSION_PROPERTY = this == KotlinReferenceData.Kind.EXTENSION_FUNCTION || this == KotlinReferenceData.Kind.EXTENSION_PROPERTY
private fun findImportableDescriptors(fqName: FqName, file: JetFile): Collection<DeclarationDescriptor> { private fun findImportableDescriptors(fqName: FqName, file: JetFile): Collection<DeclarationDescriptor> {
return file.getResolutionFacade().resolveImportReference(file, fqName, isDefaultImport = true/*TODO: temporary hack until we don't have ability to insert qualified reference into root package*/) return file.resolveImportReference(fqName, isDefaultImport = true/*TODO: temporary hack until we don't have ability to insert qualified reference into root package*/)
} }
private fun findCallableToImport(fqName: FqName, file: JetFile): CallableDescriptor? private fun findCallableToImport(fqName: FqName, file: JetFile): CallableDescriptor?
@@ -30,7 +30,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.PsiJavaFile import com.intellij.psi.PsiJavaFile
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.codeInsight.KotlinCopyPasteReferenceProcessor import org.jetbrains.kotlin.idea.codeInsight.KotlinCopyPasteReferenceProcessor
import org.jetbrains.kotlin.idea.codeInsight.KotlinReferenceData import org.jetbrains.kotlin.idea.codeInsight.KotlinReferenceData
import org.jetbrains.kotlin.idea.editor.JetEditorOptions import org.jetbrains.kotlin.idea.editor.JetEditorOptions
@@ -97,7 +97,7 @@ public class ConvertJavaCopyPastePostProcessor : CopyPastePostProcessor<TextBloc
rangeMarker.setGreedyToRight(true) rangeMarker.setGreedyToRight(true)
explicitImports.forEach { fqName -> explicitImports.forEach { fqName ->
targetFile.getResolutionFacade().resolveImportReference(targetFile, fqName).firstOrNull()?.let { targetFile.resolveImportReference(fqName).firstOrNull()?.let {
ImportInsertHelper.getInstance(project).importDescriptor(targetFile, it) ImportInsertHelper.getInstance(project).importDescriptor(targetFile, it)
} }
} }
@@ -25,6 +25,7 @@ import com.intellij.psi.search.searches.ReferencesSearch
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.intentions.IfNullToElvisIntention import org.jetbrains.kotlin.idea.intentions.IfNullToElvisIntention
import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeArgumentsIntention import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeArgumentsIntention
import org.jetbrains.kotlin.idea.intentions.SimplifyNegatedBinaryExpressionIntention import org.jetbrains.kotlin.idea.intentions.SimplifyNegatedBinaryExpressionIntention
@@ -52,7 +53,7 @@ public class J2kPostProcessor(private val formatCode: Boolean) : PostProcessor {
} }
override fun insertImport(file: JetFile, fqName: FqName) { override fun insertImport(file: JetFile, fqName: FqName) {
val descriptors = file.getResolutionFacade().resolveImportReference(file, fqName) val descriptors = file.resolveImportReference(fqName)
descriptors.firstOrNull()?.let { ImportInsertHelper.getInstance(file.getProject()).importDescriptor(file, it) } descriptors.firstOrNull()?.let { ImportInsertHelper.getInstance(file.getProject()).importDescriptor(file, it) }
} }
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.core.*
import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester
import org.jetbrains.kotlin.idea.core.refactoring.JetNameValidator import org.jetbrains.kotlin.idea.core.refactoring.JetNameValidator
@@ -90,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(), file, project) val replacement = ReplaceWithAnnotationAnalyzer.analyze(replaceWith, descriptor, element.getResolutionFacade(), project)
invoke(resolvedCall, bindingContext, replacement, project, editor) invoke(resolvedCall, bindingContext, replacement, project, editor)
} }
@@ -223,7 +224,7 @@ public abstract class DeprecatedSymbolUsageFixBase(
val file = result.getContainingJetFile() val file = result.getContainingJetFile()
replacement.fqNamesToImport replacement.fqNamesToImport
.flatMap { file.getResolutionFacade().resolveImportReference(file, it) } .flatMap { file.resolveImportReference(it) }
.forEach { ImportInsertHelper.getInstance(project).importDescriptor(file, it) } .forEach { ImportInsertHelper.getInstance(project).importDescriptor(file, it) }
result = postProcessInsertedExpression(result, wrapper.addedStatements) result = postProcessInsertedExpression(result, wrapper.addedStatements)
@@ -18,8 +18,6 @@ package org.jetbrains.kotlin.idea.quickfix
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiRecursiveElementVisitor
import org.jetbrains.kotlin.analyzer.analyzeInContext import org.jetbrains.kotlin.analyzer.analyzeInContext
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
@@ -34,13 +32,15 @@ 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
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.scopes.* import org.jetbrains.kotlin.resolve.scopes.*
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.Printer
@@ -65,21 +65,19 @@ object ReplaceWithAnnotationAnalyzer {
annotation: ReplaceWith, annotation: ReplaceWith,
symbolDescriptor: CallableDescriptor, symbolDescriptor: CallableDescriptor,
resolutionFacade: ResolutionFacade, resolutionFacade: ResolutionFacade,
file: JetFile/*TODO: drop it*/,
project: Project 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, file, project) return analyzeOriginal(annotation, originalDescriptor, resolutionFacade, project)
} }
private fun analyzeOriginal( private fun analyzeOriginal(
annotation: ReplaceWith, annotation: ReplaceWith,
symbolDescriptor: CallableDescriptor, symbolDescriptor: CallableDescriptor,
resolutionFacade: ResolutionFacade, resolutionFacade: ResolutionFacade,
file: JetFile/*TODO: drop it*/,
project: Project project: Project
): ReplacementExpression { ): ReplacementExpression {
val psiFactory = JetPsiFactory(project) val psiFactory = JetPsiFactory(project)
@@ -91,7 +89,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(file, 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)
@@ -20,7 +20,7 @@ import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.AbstractImportsTest import org.jetbrains.kotlin.AbstractImportsTest
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.util.ImportInsertHelper import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetFile
@@ -38,7 +38,7 @@ public abstract class AbstractAddImportTest : AbstractImportsTest() {
descriptorName = descriptorName.substring("class:".length()).trim() descriptorName = descriptorName.substring("class:".length()).trim()
} }
val descriptors = file.getResolutionFacade().resolveImportReference(file, FqName(descriptorName)).filter(filter) val descriptors = file.resolveImportReference(FqName(descriptorName)).filter(filter)
when { when {
descriptors.isEmpty() -> descriptors.isEmpty() ->
@@ -24,7 +24,7 @@ import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import org.jetbrains.kotlin.checkers.AbstractJetPsiCheckerTest import org.jetbrains.kotlin.checkers.AbstractJetPsiCheckerTest
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.completion.test.AbstractJvmBasicCompletionTest import org.jetbrains.kotlin.idea.completion.test.AbstractJvmBasicCompletionTest
import org.jetbrains.kotlin.idea.completion.test.ExpectedCompletionUtils import org.jetbrains.kotlin.idea.completion.test.ExpectedCompletionUtils
import org.jetbrains.kotlin.idea.completion.test.handlers.AbstractCompletionHandlerTest import org.jetbrains.kotlin.idea.completion.test.handlers.AbstractCompletionHandlerTest
@@ -51,7 +51,7 @@ public abstract class AbstractCodeFragmentHighlightingTest : AbstractJetPsiCheck
val fileText = FileUtil.loadFile(File(filePath), true) val fileText = FileUtil.loadFile(File(filePath), true)
val file = myFixture.getFile() as JetFile val file = myFixture.getFile() as JetFile
InTextDirectivesUtils.findListWithPrefixes(fileText, "// IMPORT: ").forEach { InTextDirectivesUtils.findListWithPrefixes(fileText, "// IMPORT: ").forEach {
val descriptor = file.getResolutionFacade().resolveImportReference(file, FqName(it)).singleOrNull() val descriptor = file.resolveImportReference(FqName(it)).singleOrNull()
?: error("Could not resolve descriptor to import: $it") ?: error("Could not resolve descriptor to import: $it")
ImportInsertHelper.getInstance(getProject()).importDescriptor(file, descriptor) ImportInsertHelper.getInstance(getProject()).importDescriptor(file, descriptor)
} }