From 2fdd1ade2634c4e02e3a4877fe348453e05aced8 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 13 Nov 2015 21:00:24 +0300 Subject: [PATCH] Refactored utlity for checking isVisible --- .../idea/completion/CompletionSession.kt | 2 +- .../idea/completion/smart/StaticMembers.kt | 5 +-- .../kotlin/idea/core/descriptorUtils.kt | 44 ++++++++++++------- .../kotlin/idea/quickfix/AutoImportFix.kt | 8 ++-- 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt index 9137d03eefa..caaedcd1835 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt @@ -192,7 +192,7 @@ abstract class CompletionSession( if (descriptor is TypeParameterDescriptor && !isTypeParameterVisible(descriptor)) return false if (descriptor is DeclarationDescriptorWithVisibility) { - val visible = descriptor.isVisible(inDescriptor, bindingContext, nameExpression) + val visible = descriptor.isVisible(position, callTypeAndReceiver.receiver as? KtExpression, bindingContext, resolutionFacade) if (visible) return true return completeNonAccessible && !descriptor.isFromLibrary() } diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/StaticMembers.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/StaticMembers.kt index 73a5f27f3dc..2b1fd669bf6 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/StaticMembers.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/StaticMembers.kt @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.idea.completion.fuzzyType import org.jetbrains.kotlin.idea.core.isVisible import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.util.fuzzyReturnType -import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -61,10 +60,8 @@ class StaticMembers( context: KtSimpleNameExpression, enumEntriesToSkip: Set) { - val containingDescriptor = context.getResolutionScope(bindingContext, resolutionFacade).ownerDescriptor - fun processMember(descriptor: DeclarationDescriptor) { - if (descriptor is DeclarationDescriptorWithVisibility && !descriptor.isVisible(containingDescriptor, bindingContext, context)) return + if (descriptor is DeclarationDescriptorWithVisibility && !descriptor.isVisible(context, null, bindingContext, resolutionFacade)) return val matcher: (ExpectedInfo) -> ExpectedInfoMatch if (descriptor is CallableDescriptor) { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/descriptorUtils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/descriptorUtils.kt index 269645a3a09..d186fee251d 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/descriptorUtils.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/descriptorUtils.kt @@ -17,44 +17,58 @@ package org.jetbrains.kotlin.idea.core import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde +import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.KtSimpleNameExpression -import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression +import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors +import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor +fun DeclarationDescriptorWithVisibility.isVisible(from: DeclarationDescriptor): Boolean { + return isVisible(from, null) +} + fun DeclarationDescriptorWithVisibility.isVisible( + context: PsiElement, + receiverExpression: KtExpression?, + bindingContext: BindingContext, + resolutionFacade: ResolutionFacade +): Boolean { + val resolutionScope = context.getResolutionScope(bindingContext, resolutionFacade) + val from = resolutionScope.ownerDescriptor + return isVisible(from, receiverExpression, bindingContext, resolutionScope) +} + +private fun DeclarationDescriptorWithVisibility.isVisible( from: DeclarationDescriptor, + receiverExpression: KtExpression?, bindingContext: BindingContext? = null, - element: KtSimpleNameExpression? = null + resolutionScope: LexicalScope? = null ): Boolean { if (Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, this, from)) return true - if (bindingContext == null || element == null) return false - val receiver = element.getReceiverExpression() - val type = receiver?.let { bindingContext.getType(it) } - val explicitReceiver = type?.let { ExpressionReceiver.create(receiver!!, it, bindingContext) } + if (bindingContext == null || resolutionScope == null) return false - if (explicitReceiver != null) { + if (receiverExpression != null) { + val receiverType = bindingContext.getType(receiverExpression) ?: return false + val explicitReceiver = ExpressionReceiver.create(receiverExpression, receiverType, bindingContext) return Visibilities.isVisible(explicitReceiver, this, from) } - - val resolutionScope = element.getResolutionScope(bindingContext, element.getResolutionFacade()) - val implicitReceivers = resolutionScope.getImplicitReceiversHierarchy() - for (implicitReceiver in implicitReceivers) { - if (Visibilities.isVisible(implicitReceiver.value, this, from)) return true + else { + return resolutionScope.getImplicitReceiversHierarchy().any { + Visibilities.isVisible(it.value, this, from) + } } - return false } private fun compareDescriptorsText(project: Project, d1: DeclarationDescriptor, d2: DeclarationDescriptor): Boolean { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AutoImportFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AutoImportFix.kt index 90638830544..81370fcfa8d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AutoImportFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AutoImportFix.kt @@ -44,7 +44,6 @@ import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper import org.jetbrains.kotlin.idea.core.isVisible import org.jetbrains.kotlin.idea.project.ProjectStructureUtil import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver -import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.isImportDirectiveExpression @@ -136,12 +135,11 @@ internal abstract class AutoImportFixBase(expression: T) : if (!diagnostics.any { it.getFactory() in getSupportedErrors() }) return emptyList() - val resolutionScope = element.getResolutionScope(bindingContext, file.getResolutionFacade()) - val containingDescriptor = resolutionScope.ownerDescriptor + val resolutionFacade = element.getResolutionFacade() fun isVisible(descriptor: DeclarationDescriptor): Boolean { if (descriptor is DeclarationDescriptorWithVisibility) { - return descriptor.isVisible(containingDescriptor, bindingContext, element as? KtSimpleNameExpression) + return descriptor.isVisible(element, callTypeAndReceiver.receiver as? KtExpression, bindingContext, resolutionFacade) } return true @@ -149,7 +147,7 @@ internal abstract class AutoImportFixBase(expression: T) : val result = ArrayList() - val indicesHelper = KotlinIndicesHelper(element.getResolutionFacade(), searchScope, ::isVisible) + val indicesHelper = KotlinIndicesHelper(resolutionFacade, searchScope, ::isVisible) val expression = element if (expression is KtSimpleNameExpression) {