Add BodyResolveMode parameter to resolveToDescriptor()

This commit is contained in:
Valentin Kipyatkov
2016-10-30 14:34:41 +03:00
parent a10272b236
commit 68174470c3
15 changed files with 39 additions and 25 deletions
@@ -38,12 +38,13 @@ fun KtElement.getResolutionFacade(): ResolutionFacade {
return KotlinCacheService.getInstance(project).getResolutionFacade(listOf(this)) return KotlinCacheService.getInstance(project).getResolutionFacade(listOf(this))
} }
fun KtDeclaration.resolveToDescriptor(): DeclarationDescriptor { fun KtDeclaration.resolveToDescriptor(bodyResolveMode: BodyResolveMode = BodyResolveMode.FULL): DeclarationDescriptor {
return getResolutionFacade().resolveToDescriptor(this) return getResolutionFacade().resolveToDescriptor(this, bodyResolveMode)
} }
fun KtDeclaration.resolveToDescriptorIfAny(): DeclarationDescriptor? { //TODO: BodyResolveMode.PARTIAL is not quite safe!
return analyze(BodyResolveMode.PARTIAL).get(BindingContext.DECLARATION_TO_DESCRIPTOR, this) fun KtDeclaration.resolveToDescriptorIfAny(bodyResolveMode: BodyResolveMode = BodyResolveMode.PARTIAL): DeclarationDescriptor? {
return analyze(bodyResolveMode).get(BindingContext.DECLARATION_TO_DESCRIPTOR, this)
} }
fun KtFile.resolveImportReference(fqName: FqName): Collection<DeclarationDescriptor> { fun KtFile.resolveImportReference(fqName: FqName): Collection<DeclarationDescriptor> {
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt; import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
import org.jetbrains.kotlin.types.DeferredType; import org.jetbrains.kotlin.types.DeferredType;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
@@ -60,7 +61,7 @@ public class QuickFixUtil {
public static KotlinType getDeclarationReturnType(KtNamedDeclaration declaration) { public static KotlinType getDeclarationReturnType(KtNamedDeclaration declaration) {
PsiFile file = declaration.getContainingFile(); PsiFile file = declaration.getContainingFile();
if (!(file instanceof KtFile)) return null; if (!(file instanceof KtFile)) return null;
DeclarationDescriptor descriptor = ResolutionUtils.resolveToDescriptor(declaration); DeclarationDescriptor descriptor = ResolutionUtils.resolveToDescriptor(declaration, BodyResolveMode.FULL);
if (!(descriptor instanceof CallableDescriptor)) return null; if (!(descriptor instanceof CallableDescriptor)) return null;
KotlinType type = ((CallableDescriptor) descriptor).getReturnType(); KotlinType type = ((CallableDescriptor) descriptor).getReturnType();
if (type instanceof DeferredType) { if (type instanceof DeferredType) {
@@ -34,7 +34,7 @@ interface ResolutionFacade {
fun analyzeFullyAndGetResult(elements: Collection<KtElement>): AnalysisResult fun analyzeFullyAndGetResult(elements: Collection<KtElement>): AnalysisResult
fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor fun resolveToDescriptor(declaration: KtDeclaration, bodyResolveMode: BodyResolveMode = BodyResolveMode.FULL): DeclarationDescriptor
val moduleDescriptor: ModuleDescriptor val moduleDescriptor: ModuleDescriptor
@@ -27,7 +27,9 @@ import org.jetbrains.kotlin.idea.project.ResolveElementCache
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.AbsentDescriptorHandler
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
@@ -58,9 +60,16 @@ internal class ResolutionFacadeImpl(
override fun analyzeFullyAndGetResult(elements: Collection<KtElement>): AnalysisResult override fun analyzeFullyAndGetResult(elements: Collection<KtElement>): AnalysisResult
= projectFacade.getAnalysisResultsForElements(elements) = projectFacade.getAnalysisResultsForElements(elements)
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor { override fun resolveToDescriptor(declaration: KtDeclaration, bodyResolveMode: BodyResolveMode): DeclarationDescriptor {
val resolveSession = projectFacade.resolverForModuleInfo(declaration.getModuleInfo()).componentProvider.get<ResolveSession>() if (KtPsiUtil.isLocal(declaration)) {
return resolveSession.resolveToDescriptor(declaration) val bindingContext = analyze(declaration, bodyResolveMode)
return bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration]
?: getFrontendService(moduleInfo, AbsentDescriptorHandler::class.java).diagnoseDescriptorNotFound(declaration)
}
else {
val resolveSession = projectFacade.resolverForModuleInfo(declaration.getModuleInfo()).componentProvider.get<ResolveSession>()
return resolveSession.resolveToDescriptor(declaration)
}
} }
override fun <T : Any> getFrontendService(serviceClass: Class<T>): T = getFrontendService(moduleInfo, serviceClass) override fun <T : Any> getFrontendService(serviceClass: Class<T>): T = getFrontendService(moduleInfo, serviceClass)
@@ -24,7 +24,7 @@ import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import com.intellij.util.SmartList import com.intellij.util.SmartList
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.completion.* import org.jetbrains.kotlin.idea.completion.*
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.core.*
@@ -293,9 +293,7 @@ class SmartCompletion(
if (declaration != null) { if (declaration != null) {
val originalDeclaration = toFromOriginalFileMapper.toOriginalFile(declaration) val originalDeclaration = toFromOriginalFileMapper.toOriginalFile(declaration)
if (originalDeclaration != null) { if (originalDeclaration != null) {
// we don't use resolveToDescriptor() here because it uses BodyResolveMode.FULL! val originalDescriptor = originalDeclaration.resolveToDescriptor(BodyResolveMode.PARTIAL) as? CallableDescriptor
val bindingContext = originalDeclaration.analyze(BodyResolveMode.PARTIAL)
val originalDescriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, originalDeclaration] as? CallableDescriptor
val returnType = originalDescriptor?.returnType val returnType = originalDescriptor?.returnType
if (returnType != null && !returnType.isError) { if (returnType != null && !returnType.isError) {
return listOf(ExpectedInfo(returnType, declaration.name, null)) return listOf(ExpectedInfo(returnType, declaration.name, null))
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
import org.jetbrains.kotlin.idea.core.DescriptorUtilsKt; import org.jetbrains.kotlin.idea.core.DescriptorUtilsKt;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import java.util.Collection; import java.util.Collection;
@@ -61,7 +62,7 @@ public class GotoSuperActionHandler implements CodeInsightActionHandler {
KtObjectDeclaration.class); KtObjectDeclaration.class);
if (declaration == null) return; if (declaration == null) return;
DeclarationDescriptor descriptor = ResolutionUtils.resolveToDescriptor(declaration); DeclarationDescriptor descriptor = ResolutionUtils.resolveToDescriptor(declaration, BodyResolveMode.PARTIAL);
List<PsiElement> superDeclarations = findSuperDeclarations(descriptor); List<PsiElement> superDeclarations = findSuperDeclarations(descriptor);
@@ -22,13 +22,14 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils; import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
import org.jetbrains.kotlin.psi.KtNamedFunction; import org.jetbrains.kotlin.psi.KtNamedFunction;
import org.jetbrains.kotlin.renderer.DescriptorRenderer; import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
public class KtFunctionPsiElementCellRenderer extends DefaultPsiElementCellRenderer { public class KtFunctionPsiElementCellRenderer extends DefaultPsiElementCellRenderer {
@Override @Override
public String getElementText(PsiElement element) { public String getElementText(PsiElement element) {
if (element instanceof KtNamedFunction) { if (element instanceof KtNamedFunction) {
KtNamedFunction function = (KtNamedFunction) element; KtNamedFunction function = (KtNamedFunction) element;
DeclarationDescriptor descriptor = ResolutionUtils.resolveToDescriptor(function); DeclarationDescriptor descriptor = ResolutionUtils.resolveToDescriptor(function, BodyResolveMode.PARTIAL);
return DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(descriptor); return DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(descriptor);
} }
return super.getElementText(element); return super.getElementText(element);
@@ -51,6 +51,7 @@ import org.jetbrains.kotlin.renderer.render
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.isHiddenInResolution import org.jetbrains.kotlin.resolve.isHiddenInResolution
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.collectSyntheticExtensionProperties import org.jetbrains.kotlin.resolve.scopes.collectSyntheticExtensionProperties
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
@@ -190,7 +191,7 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection(), Clean
override fun invoke(project: Project, editor: Editor?, file: KtFile) { override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val declaration = element val declaration = element
val fqName = declaration.resolveToDescriptor().importableFqName val fqName = declaration.resolveToDescriptor(BodyResolveMode.PARTIAL).importableFqName
if (fqName != null) { if (fqName != null) {
ProgressManager.getInstance().run( ProgressManager.getInstance().run(
object : Task.Modal(project, "Searching for imports to delete", true) { object : Task.Modal(project, "Searching for imports to delete", true) {
@@ -22,12 +22,13 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.util.OperatorChecks import org.jetbrains.kotlin.util.OperatorChecks
class AddOperatorModifierIntention : SelfTargetingRangeIntention<KtNamedFunction>(KtNamedFunction::class.java, "Add 'operator' modifier") { class AddOperatorModifierIntention : SelfTargetingRangeIntention<KtNamedFunction>(KtNamedFunction::class.java, "Add 'operator' modifier") {
override fun applicabilityRange(element: KtNamedFunction): TextRange? { override fun applicabilityRange(element: KtNamedFunction): TextRange? {
val nameIdentifier = element.nameIdentifier ?: return null val nameIdentifier = element.nameIdentifier ?: return null
val functionDescriptor = element.resolveToDescriptor() as? FunctionDescriptor ?: return null val functionDescriptor = element.resolveToDescriptor(BodyResolveMode.PARTIAL) as? FunctionDescriptor ?: return null
if (functionDescriptor.isOperator || !OperatorChecks.check(functionDescriptor).isSuccess) return null if (functionDescriptor.isOperator || !OperatorChecks.check(functionDescriptor).isSuccess) return null
return nameIdentifier.textRange return nameIdentifier.textRange
} }
@@ -109,7 +109,7 @@ class ConvertFunctionToPropertyIntention : SelfTargetingIntention<KtNamedFunctio
if (callable is KtNamedFunction) { if (callable is KtNamedFunction) {
if (callable.typeReference == null) { if (callable.typeReference == null) {
val functionDescriptor = callable.resolveToDescriptor() as FunctionDescriptor val functionDescriptor = callable.resolveToDescriptor(BodyResolveMode.PARTIAL) as FunctionDescriptor
val type = functionDescriptor.returnType val type = functionDescriptor.returnType
val typeToInsert = when { val typeToInsert = when {
type == null || type.isError -> null type == null || type.isError -> null
@@ -37,13 +37,14 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class ConvertSealedClassToEnumIntention : SelfTargetingRangeIntention<KtClass>(KtClass::class.java, "Convert to enum class") { class ConvertSealedClassToEnumIntention : SelfTargetingRangeIntention<KtClass>(KtClass::class.java, "Convert to enum class") {
override fun applicabilityRange(element: KtClass): TextRange? { override fun applicabilityRange(element: KtClass): TextRange? {
val nameIdentifier = element.nameIdentifier ?: return null val nameIdentifier = element.nameIdentifier ?: return null
val sealedKeyword = element.modifierList?.getModifier(KtTokens.SEALED_KEYWORD) ?: return null val sealedKeyword = element.modifierList?.getModifier(KtTokens.SEALED_KEYWORD) ?: return null
val classDescriptor = element.resolveToDescriptor() as ClassDescriptor val classDescriptor = element.resolveToDescriptor(BodyResolveMode.PARTIAL) as ClassDescriptor
if (classDescriptor.getSuperClassNotAny() != null) return null if (classDescriptor.getSuperClassNotAny() != null) return null
return TextRange(sealedKeyword.startOffset, nameIdentifier.endOffset) return TextRange(sealedKeyword.startOffset, nameIdentifier.endOffset)
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.util.CommentSaver
import org.jetbrains.kotlin.idea.util.psi.patternMatching.matches import org.jetbrains.kotlin.idea.util.psi.patternMatching.matches
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.types.typeUtil.isUnit
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
@@ -205,7 +206,7 @@ class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>(KtIfEx
is KtNamedFunction -> { is KtNamedFunction -> {
if (parent.bodyExpression == expression) { if (parent.bodyExpression == expression) {
if (!parent.hasBlockBody()) return null if (!parent.hasBlockBody()) return null
val returnType = (parent.resolveToDescriptor() as FunctionDescriptor).returnType val returnType = (parent.resolveToDescriptor(BodyResolveMode.PARTIAL) as FunctionDescriptor).returnType
if (returnType == null || !returnType.isUnit()) return null if (returnType == null || !returnType.isUnit()) return null
return KtPsiFactory(expression).createExpression("return") return KtPsiFactory(expression).createExpression("return")
} }
@@ -29,9 +29,9 @@ import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
import org.jetbrains.kotlin.idea.resolve.ideService import org.jetbrains.kotlin.idea.resolve.ideService
import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtDeclarationWithInitializer
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtForExpression import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.psi.KtDeclarationWithInitializer
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class SuggestVariableNameMacro : Macro() { class SuggestVariableNameMacro : Macro() {
@@ -71,7 +71,7 @@ class SuggestVariableNameMacro : Macro() {
suggestIterationVariableName(parent, nameValidator)?.let { return it } suggestIterationVariableName(parent, nameValidator)?.let { return it }
} }
val descriptor = declaration.resolveToDescriptor() as? VariableDescriptor ?: return emptyList() val descriptor = declaration.resolveToDescriptor(BodyResolveMode.PARTIAL) as? VariableDescriptor ?: return emptyList()
return KotlinNameSuggester.suggestNamesByType(descriptor.type, nameValidator, null) return KotlinNameSuggester.suggestNamesByType(descriptor.type, nameValidator, null)
} }
@@ -27,7 +27,6 @@ import com.intellij.psi.search.LocalSearchScope
import com.intellij.util.ProcessingContext import com.intellij.util.ProcessingContext
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
@@ -65,7 +64,7 @@ private fun KtExpression.getBundleNameByContext(): String? {
val expression = KtPsiUtil.safeDeparenthesize(this) val expression = KtPsiUtil.safeDeparenthesize(this)
val parent = expression.parent val parent = expression.parent
(parent as? KtProperty)?.let { return it.resolveToDescriptor().getBundleNameByAnnotation() } (parent as? KtProperty)?.let { return it.resolveToDescriptor(BodyResolveMode.PARTIAL).getBundleNameByAnnotation() }
val bindingContext = expression.analyze(BodyResolveMode.PARTIAL) val bindingContext = expression.analyze(BodyResolveMode.PARTIAL)
val resolvedCall = val resolvedCall =
@@ -768,7 +768,7 @@ fun KtExpression.removeTemplateEntryBracesIfPossible(): KtExpression {
} }
fun dropOverrideKeywordIfNecessary(element: KtNamedDeclaration) { fun dropOverrideKeywordIfNecessary(element: KtNamedDeclaration) {
val callableDescriptor = element.resolveToDescriptor() as? CallableDescriptor ?: return val callableDescriptor = element.resolveToDescriptor(BodyResolveMode.PARTIAL) as? CallableDescriptor ?: return
if (callableDescriptor.overriddenDescriptors.isEmpty()) { if (callableDescriptor.overriddenDescriptors.isEmpty()) {
element.removeModifier(KtTokens.OVERRIDE_KEYWORD) element.removeModifier(KtTokens.OVERRIDE_KEYWORD)
} }