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
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.psi.JetReturnExpression
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.BindingContext.LABEL_TARGET
import org.jetbrains.kotlin.resolve.BindingContext.FUNCTION
import org.jetbrains.kotlin.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.JetDeclarationWithBody
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
import org.jetbrains.kotlin.psi.JetCallableDeclaration
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
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.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
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.psi.JetReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.types.JetType
public val DeclarationDescriptor.importableFqName: FqName?
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
public fun JetReferenceExpression.getImportableTargets(bindingContext: BindingContext): Collection<DeclarationDescriptor> {
val targets = bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, this]?.let { listOf(it) }
?: bindingContext[BindingContext.REFERENCE_TARGET, this]?.let { listOf(it) }
?: bindingContext[BindingContext.AMBIGUOUS_REFERENCE_TARGET, this]
?: listOf()
?: getReferenceTargets(bindingContext)
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.JetReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
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) {
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
val targetDescriptor = context[BindingContext.REFERENCE_TARGET, expression]
if (targetDescriptor != null) {
return listOf(targetDescriptor)
}
return context[BindingContext.AMBIGUOUS_REFERENCE_TARGET, expression].orEmpty()
}
override fun getTargetDescriptors(context: BindingContext) = expression.getReferenceTargets(context)
}
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.psiUtil.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
@@ -294,14 +295,8 @@ public class KotlinCompletionContributor : CompletionContributor() {
val nameRef = nameToken.getParent() as? JetNameReferenceExpression ?: return null
val bindingContext = nameRef.getResolutionFacade().analyze(nameRef, BodyResolveMode.PARTIAL)
val target = bindingContext[BindingContext.REFERENCE_TARGET, nameRef]
val targets = if (target != null) {
listOf(target)
}
else {
bindingContext[BindingContext.AMBIGUOUS_REFERENCE_TARGET, nameRef] ?: return null
}
if (targets.all { it is FunctionDescriptor || it is ClassDescriptor && it.getKind() == ClassKind.CLASS }) {
val targets = nameRef.getReferenceTargets(bindingContext)
if (targets.isNotEmpty() && targets.all { it is FunctionDescriptor || it is ClassDescriptor && it.getKind() == ClassKind.CLASS }) {
return CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED + ">".repeat(balance) + "$"
}
else {