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))
}
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<DeclarationDescriptor> {
@@ -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) {
@@ -34,7 +34,7 @@ interface ResolutionFacade {
fun analyzeFullyAndGetResult(elements: Collection<KtElement>): AnalysisResult
fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor
fun resolveToDescriptor(declaration: KtDeclaration, bodyResolveMode: BodyResolveMode = BodyResolveMode.FULL): DeclarationDescriptor
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.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<KtElement>): AnalysisResult
= projectFacade.getAnalysisResultsForElements(elements)
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor {
val resolveSession = projectFacade.resolverForModuleInfo(declaration.getModuleInfo()).componentProvider.get<ResolveSession>()
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<ResolveSession>()
return resolveSession.resolveToDescriptor(declaration)
}
}
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.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))
@@ -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<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.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);
@@ -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) {
@@ -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>(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
}
@@ -109,7 +109,7 @@ class ConvertFunctionToPropertyIntention : SelfTargetingIntention<KtNamedFunctio
if (callable is KtNamedFunction) {
if (callable.typeReference == null) {
val functionDescriptor = callable.resolveToDescriptor() as FunctionDescriptor
val functionDescriptor = callable.resolveToDescriptor(BodyResolveMode.PARTIAL) as FunctionDescriptor
val type = functionDescriptor.returnType
val typeToInsert = when {
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.startOffset
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") {
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)
@@ -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<KtIfExpression>(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")
}
@@ -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)
}
@@ -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 =
@@ -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)
}