Refactoring: Introduce getReferenceTargets() function

This commit is contained in:
Alexey Sedunov
2015-05-19 17:52:54 +03:00
parent 640f07969a
commit 036e2c585b
4 changed files with 18 additions and 33 deletions
@@ -16,18 +16,16 @@
package org.jetbrains.kotlin.resolve.bindingContextUtil package org.jetbrains.kotlin.resolve.bindingContextUtil
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.psi.JetReturnExpression
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.BindingContext.LABEL_TARGET import org.jetbrains.kotlin.resolve.BindingContext.LABEL_TARGET
import org.jetbrains.kotlin.resolve.BindingContext.FUNCTION import org.jetbrains.kotlin.resolve.BindingContext.FUNCTION
import org.jetbrains.kotlin.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR import org.jetbrains.kotlin.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.JetDeclarationWithBody
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
import org.jetbrains.kotlin.psi.JetCallableDeclaration import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
@@ -73,3 +71,7 @@ public fun BindingContext.getDataFlowInfo(expression: JetExpression?): DataFlowI
public fun JetExpression.isUnreachableCode(context: BindingContext): Boolean = context[BindingContext.UNREACHABLE_CODE, this]!! public fun JetExpression.isUnreachableCode(context: BindingContext): Boolean = context[BindingContext.UNREACHABLE_CODE, this]!!
public fun JetExpression.getReferenceTargets(context: BindingContext): Collection<DeclarationDescriptor> {
val targetDescriptor = if (this is JetReferenceExpression) context[BindingContext.REFERENCE_TARGET, this] else null
return targetDescriptor?.let { listOf(it) } ?: context[BindingContext.AMBIGUOUS_REFERENCE_TARGET, this].orEmpty()
}
@@ -16,19 +16,14 @@
package org.jetbrains.kotlin.idea.imports package org.jetbrains.kotlin.idea.imports
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.psi.JetReferenceExpression
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.*
public val DeclarationDescriptor.importableFqName: FqName? public val DeclarationDescriptor.importableFqName: FqName?
get() { get() {
@@ -64,8 +59,6 @@ public fun JetType.canBeReferencedViaImport(): Boolean {
// for cases when class qualifier refers companion object treats it like reference to class itself // for cases when class qualifier refers companion object treats it like reference to class itself
public fun JetReferenceExpression.getImportableTargets(bindingContext: BindingContext): Collection<DeclarationDescriptor> { public fun JetReferenceExpression.getImportableTargets(bindingContext: BindingContext): Collection<DeclarationDescriptor> {
val targets = bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, this]?.let { listOf(it) } val targets = bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, this]?.let { listOf(it) }
?: bindingContext[BindingContext.REFERENCE_TARGET, this]?.let { listOf(it) } ?: getReferenceTargets(bindingContext)
?: bindingContext[BindingContext.AMBIGUOUS_REFERENCE_TARGET, this]
?: listOf()
return targets.map { it.getImportableDescriptor() }.toSet() return targets.map { it.getImportableDescriptor() }.toSet()
} }
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.psi.JetElement import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.JetReferenceExpression import org.jetbrains.kotlin.psi.JetReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
import java.util.Collections import java.util.Collections
@@ -116,13 +117,7 @@ public abstract class AbstractJetReference<T : JetElement>(element: T)
} }
public abstract class JetSimpleReference<T : JetReferenceExpression>(expression: T) : AbstractJetReference<T>(expression) { public abstract class JetSimpleReference<T : JetReferenceExpression>(expression: T) : AbstractJetReference<T>(expression) {
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> { override fun getTargetDescriptors(context: BindingContext) = expression.getReferenceTargets(context)
val targetDescriptor = context[BindingContext.REFERENCE_TARGET, expression]
if (targetDescriptor != null) {
return listOf(targetDescriptor)
}
return context[BindingContext.AMBIGUOUS_REFERENCE_TARGET, expression].orEmpty()
}
} }
public abstract class JetMultiReference<T : JetElement>(expression: T) : AbstractJetReference<T>(expression) public abstract class JetMultiReference<T : JetElement>(expression: T) : AbstractJetReference<T>(expression)
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.lexer.JetTokens
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.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
@@ -294,14 +295,8 @@ public class KotlinCompletionContributor : CompletionContributor() {
val nameRef = nameToken.getParent() as? JetNameReferenceExpression ?: return null val nameRef = nameToken.getParent() as? JetNameReferenceExpression ?: return null
val bindingContext = nameRef.getResolutionFacade().analyze(nameRef, BodyResolveMode.PARTIAL) val bindingContext = nameRef.getResolutionFacade().analyze(nameRef, BodyResolveMode.PARTIAL)
val target = bindingContext[BindingContext.REFERENCE_TARGET, nameRef] val targets = nameRef.getReferenceTargets(bindingContext)
val targets = if (target != null) { if (targets.isNotEmpty() && targets.all { it is FunctionDescriptor || it is ClassDescriptor && it.getKind() == ClassKind.CLASS }) {
listOf(target)
}
else {
bindingContext[BindingContext.AMBIGUOUS_REFERENCE_TARGET, nameRef] ?: return null
}
if (targets.all { it is FunctionDescriptor || it is ClassDescriptor && it.getKind() == ClassKind.CLASS }) {
return CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED + ">".repeat(balance) + "$" return CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED + ">".repeat(balance) + "$"
} }
else { else {