From 68174470c3715d7933ebb92d04ea8d7cae712e47 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Sun, 30 Oct 2016 14:34:41 +0300 Subject: [PATCH] Add BodyResolveMode parameter to resolveToDescriptor() --- .../kotlin/idea/caches/resolve/resolutionApi.kt | 9 +++++---- .../kotlin/idea/core/quickfix/QuickFixUtil.java | 3 ++- .../kotlin/idea/resolve/ResolutionFacade.kt | 2 +- .../idea/caches/resolve/ResolutionFacadeImpl.kt | 15 ++++++++++++--- .../idea/completion/smart/SmartCompletion.kt | 6 ++---- .../idea/codeInsight/GotoSuperActionHandler.java | 3 ++- .../KtFunctionPsiElementCellRenderer.java | 3 ++- .../ConflictingExtensionPropertyInspection.kt | 3 ++- .../intentions/AddOperatorModifierIntention.kt | 3 ++- .../ConvertFunctionToPropertyIntention.kt | 2 +- .../ConvertSealedClassToEnumIntention.kt | 3 ++- .../idea/intentions/InvertIfConditionIntention.kt | 3 ++- .../macro/SuggestVariableNameMacro.kt | 4 ++-- .../kotlin/idea/properties/referenceProviders.kt | 3 +-- .../idea/refactoring/kotlinRefactoringUtil.kt | 2 +- 15 files changed, 39 insertions(+), 25 deletions(-) diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/caches/resolve/resolutionApi.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/caches/resolve/resolutionApi.kt index a4d600fe20e..54d99d001bd 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/caches/resolve/resolutionApi.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/caches/resolve/resolutionApi.kt @@ -38,12 +38,13 @@ fun KtElement.getResolutionFacade(): ResolutionFacade { return KotlinCacheService.getInstance(project).getResolutionFacade(listOf(this)) } -fun KtDeclaration.resolveToDescriptor(): DeclarationDescriptor { - return getResolutionFacade().resolveToDescriptor(this) +fun KtDeclaration.resolveToDescriptor(bodyResolveMode: BodyResolveMode = BodyResolveMode.FULL): DeclarationDescriptor { + return getResolutionFacade().resolveToDescriptor(this, bodyResolveMode) } -fun KtDeclaration.resolveToDescriptorIfAny(): DeclarationDescriptor? { - return analyze(BodyResolveMode.PARTIAL).get(BindingContext.DECLARATION_TO_DESCRIPTOR, this) +//TODO: BodyResolveMode.PARTIAL is not quite safe! +fun KtDeclaration.resolveToDescriptorIfAny(bodyResolveMode: BodyResolveMode = BodyResolveMode.PARTIAL): DeclarationDescriptor? { + return analyze(bodyResolveMode).get(BindingContext.DECLARATION_TO_DESCRIPTOR, this) } fun KtFile.resolveImportReference(fqName: FqName): Collection { diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/core/quickfix/QuickFixUtil.java b/idea/ide-common/src/org/jetbrains/kotlin/idea/core/quickfix/QuickFixUtil.java index f44993bfc0a..dc31f67cd00 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/core/quickfix/QuickFixUtil.java +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/core/quickfix/QuickFixUtil.java @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt; 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.KotlinType; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; @@ -60,7 +61,7 @@ public class QuickFixUtil { public static KotlinType getDeclarationReturnType(KtNamedDeclaration declaration) { PsiFile file = declaration.getContainingFile(); if (!(file instanceof KtFile)) return null; - DeclarationDescriptor descriptor = ResolutionUtils.resolveToDescriptor(declaration); + DeclarationDescriptor descriptor = ResolutionUtils.resolveToDescriptor(declaration, BodyResolveMode.FULL); if (!(descriptor instanceof CallableDescriptor)) return null; KotlinType type = ((CallableDescriptor) descriptor).getReturnType(); if (type instanceof DeferredType) { diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/resolve/ResolutionFacade.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/resolve/ResolutionFacade.kt index fe3db874b19..8968d444d2b 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/resolve/ResolutionFacade.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/resolve/ResolutionFacade.kt @@ -34,7 +34,7 @@ interface ResolutionFacade { fun analyzeFullyAndGetResult(elements: Collection): AnalysisResult - fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor + fun resolveToDescriptor(declaration: KtDeclaration, bodyResolveMode: BodyResolveMode = BodyResolveMode.FULL): DeclarationDescriptor val moduleDescriptor: ModuleDescriptor diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ResolutionFacadeImpl.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ResolutionFacadeImpl.kt index 3edf91c093e..a48370be7e8 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ResolutionFacadeImpl.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ResolutionFacadeImpl.kt @@ -27,7 +27,9 @@ import org.jetbrains.kotlin.idea.project.ResolveElementCache import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtPsiUtil 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.ResolveSession @@ -58,9 +60,16 @@ internal class ResolutionFacadeImpl( override fun analyzeFullyAndGetResult(elements: Collection): AnalysisResult = projectFacade.getAnalysisResultsForElements(elements) - override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor { - val resolveSession = projectFacade.resolverForModuleInfo(declaration.getModuleInfo()).componentProvider.get() - return resolveSession.resolveToDescriptor(declaration) + override fun resolveToDescriptor(declaration: KtDeclaration, bodyResolveMode: BodyResolveMode): DeclarationDescriptor { + if (KtPsiUtil.isLocal(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() + return resolveSession.resolveToDescriptor(declaration) + } } override fun getFrontendService(serviceClass: Class): T = getFrontendService(moduleInfo, serviceClass) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt index 6356278040f..3cede1cd5b7 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt @@ -24,7 +24,7 @@ import com.intellij.openapi.progress.ProgressManager import com.intellij.psi.search.GlobalSearchScope import com.intellij.util.SmartList 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.handlers.WithTailInsertHandler import org.jetbrains.kotlin.idea.core.* @@ -293,9 +293,7 @@ class SmartCompletion( if (declaration != null) { val originalDeclaration = toFromOriginalFileMapper.toOriginalFile(declaration) if (originalDeclaration != null) { - // we don't use resolveToDescriptor() here because it uses BodyResolveMode.FULL! - val bindingContext = originalDeclaration.analyze(BodyResolveMode.PARTIAL) - val originalDescriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, originalDeclaration] as? CallableDescriptor + val originalDescriptor = originalDeclaration.resolveToDescriptor(BodyResolveMode.PARTIAL) as? CallableDescriptor val returnType = originalDescriptor?.returnType if (returnType != null && !returnType.isError) { return listOf(ExpectedInfo(returnType, declaration.name, null)) diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/GotoSuperActionHandler.java b/idea/src/org/jetbrains/kotlin/idea/codeInsight/GotoSuperActionHandler.java index 4c364729ace..d5ba25703c2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/GotoSuperActionHandler.java +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/GotoSuperActionHandler.java @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils; import org.jetbrains.kotlin.idea.core.DescriptorUtilsKt; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode; import org.jetbrains.kotlin.types.KotlinType; import java.util.Collection; @@ -61,7 +62,7 @@ public class GotoSuperActionHandler implements CodeInsightActionHandler { KtObjectDeclaration.class); if (declaration == null) return; - DeclarationDescriptor descriptor = ResolutionUtils.resolveToDescriptor(declaration); + DeclarationDescriptor descriptor = ResolutionUtils.resolveToDescriptor(declaration, BodyResolveMode.PARTIAL); List superDeclarations = findSuperDeclarations(descriptor); diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KtFunctionPsiElementCellRenderer.java b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KtFunctionPsiElementCellRenderer.java index f1db2974da0..319ec0a33c7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/KtFunctionPsiElementCellRenderer.java +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/KtFunctionPsiElementCellRenderer.java @@ -22,13 +22,14 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils; import org.jetbrains.kotlin.psi.KtNamedFunction; import org.jetbrains.kotlin.renderer.DescriptorRenderer; +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode; public class KtFunctionPsiElementCellRenderer extends DefaultPsiElementCellRenderer { @Override public String getElementText(PsiElement element) { if (element instanceof KtNamedFunction) { 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 super.getElementText(element); diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ConflictingExtensionPropertyInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ConflictingExtensionPropertyInspection.kt index 32ecc1d5d43..0318ca98278 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/ConflictingExtensionPropertyInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ConflictingExtensionPropertyInspection.kt @@ -51,6 +51,7 @@ import org.jetbrains.kotlin.renderer.render import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess 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.collectSyntheticExtensionProperties import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor @@ -190,7 +191,7 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection(), Clean override fun invoke(project: Project, editor: Editor?, file: KtFile) { val declaration = element - val fqName = declaration.resolveToDescriptor().importableFqName + val fqName = declaration.resolveToDescriptor(BodyResolveMode.PARTIAL).importableFqName if (fqName != null) { ProgressManager.getInstance().run( object : Task.Modal(project, "Searching for imports to delete", true) { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/AddOperatorModifierIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/AddOperatorModifierIntention.kt index d7bb2e15bf7..df3f2feadc5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/AddOperatorModifierIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/AddOperatorModifierIntention.kt @@ -22,12 +22,13 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.util.OperatorChecks class AddOperatorModifierIntention : SelfTargetingRangeIntention(KtNamedFunction::class.java, "Add 'operator' modifier") { override fun applicabilityRange(element: KtNamedFunction): TextRange? { 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 return nameIdentifier.textRange } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionToPropertyIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionToPropertyIntention.kt index ebe211aed27..3ec5a18f510 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionToPropertyIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionToPropertyIntention.kt @@ -109,7 +109,7 @@ class ConvertFunctionToPropertyIntention : SelfTargetingIntention null diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSealedClassToEnumIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSealedClassToEnumIntention.kt index 0d5510a9714..0af2a64e2a6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSealedClassToEnumIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSealedClassToEnumIntention.kt @@ -37,13 +37,14 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode class ConvertSealedClassToEnumIntention : SelfTargetingRangeIntention(KtClass::class.java, "Convert to enum class") { override fun applicabilityRange(element: KtClass): TextRange? { val nameIdentifier = element.nameIdentifier ?: 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 return TextRange(sealedKeyword.startOffset, nameIdentifier.endOffset) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/InvertIfConditionIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/InvertIfConditionIntention.kt index ff7a3c4f497..d93fb9563cf 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/InvertIfConditionIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/InvertIfConditionIntention.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.util.CommentSaver import org.jetbrains.kotlin.idea.util.psi.patternMatching.matches import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull @@ -205,7 +206,7 @@ class InvertIfConditionIntention : SelfTargetingIntention(KtIfEx is KtNamedFunction -> { if (parent.bodyExpression == expression) { 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 return KtPsiFactory(expression).createExpression("return") } diff --git a/idea/src/org/jetbrains/kotlin/idea/liveTemplates/macro/SuggestVariableNameMacro.kt b/idea/src/org/jetbrains/kotlin/idea/liveTemplates/macro/SuggestVariableNameMacro.kt index 3f2c54aa00b..f412460de19 100644 --- a/idea/src/org/jetbrains/kotlin/idea/liveTemplates/macro/SuggestVariableNameMacro.kt +++ b/idea/src/org/jetbrains/kotlin/idea/liveTemplates/macro/SuggestVariableNameMacro.kt @@ -29,9 +29,9 @@ import org.jetbrains.kotlin.idea.core.KotlinNameSuggester import org.jetbrains.kotlin.idea.resolve.ideService import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.psi.KtCallableDeclaration +import org.jetbrains.kotlin.psi.KtDeclarationWithInitializer import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtForExpression -import org.jetbrains.kotlin.psi.KtDeclarationWithInitializer import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode class SuggestVariableNameMacro : Macro() { @@ -71,7 +71,7 @@ class SuggestVariableNameMacro : Macro() { 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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/properties/referenceProviders.kt b/idea/src/org/jetbrains/kotlin/idea/properties/referenceProviders.kt index 206467f082a..88d8ad5592d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/properties/referenceProviders.kt +++ b/idea/src/org/jetbrains/kotlin/idea/properties/referenceProviders.kt @@ -27,7 +27,6 @@ import com.intellij.psi.search.LocalSearchScope import com.intellij.util.ProcessingContext import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget @@ -65,7 +64,7 @@ private fun KtExpression.getBundleNameByContext(): String? { val expression = KtPsiUtil.safeDeparenthesize(this) 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 resolvedCall = diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt index c9248af80b0..bfb75a92d6f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt @@ -768,7 +768,7 @@ fun KtExpression.removeTemplateEntryBracesIfPossible(): KtExpression { } fun dropOverrideKeywordIfNecessary(element: KtNamedDeclaration) { - val callableDescriptor = element.resolveToDescriptor() as? CallableDescriptor ?: return + val callableDescriptor = element.resolveToDescriptor(BodyResolveMode.PARTIAL) as? CallableDescriptor ?: return if (callableDescriptor.overriddenDescriptors.isEmpty()) { element.removeModifier(KtTokens.OVERRIDE_KEYWORD) }