JetReference.resolveToDescriptors() requires BindingContext
This commit is contained in:
+3
-1
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
|
||||
class JetMultiDeclarationReference(element: JetMultiDeclaration) : JetMultiReference<JetMultiDeclaration>(element) {
|
||||
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||
@@ -39,7 +40,8 @@ class JetMultiDeclarationReference(element: JetMultiDeclaration) : JetMultiRefer
|
||||
}
|
||||
|
||||
override fun canRename(): Boolean {
|
||||
return resolveToDescriptors().all { it is CallableMemberDescriptor && it.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED}
|
||||
val bindingContext = expression.analyze() //TODO: should it use full body resolve?
|
||||
return resolveToDescriptors(bindingContext).all { it is CallableMemberDescriptor && it.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED}
|
||||
}
|
||||
|
||||
override fun handleElementRename(newElementName: String?): PsiElement? {
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||
|
||||
public trait JetReference : PsiPolyVariantReference {
|
||||
public fun resolveToDescriptors(): Collection<DeclarationDescriptor>
|
||||
public fun resolveToDescriptors(bindingContext: BindingContext): Collection<DeclarationDescriptor>
|
||||
}
|
||||
|
||||
public abstract class AbstractJetReference<T : JetElement>(element: T)
|
||||
@@ -72,8 +72,8 @@ public abstract class AbstractJetReference<T : JetElement>(element: T)
|
||||
return resolveToPsiElements(bindingContext, getTargetDescriptors(bindingContext))
|
||||
}
|
||||
|
||||
override fun resolveToDescriptors(): Collection<DeclarationDescriptor> {
|
||||
return getTargetDescriptors(expression.analyze())
|
||||
override fun resolveToDescriptors(bindingContext: BindingContext): Collection<DeclarationDescriptor> {
|
||||
return getTargetDescriptors(bindingContext)
|
||||
}
|
||||
|
||||
private fun resolveToPsiElements(context: BindingContext, targetDescriptors: Collection<DeclarationDescriptor>): Collection<PsiElement> {
|
||||
|
||||
@@ -119,7 +119,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Kotlin
|
||||
|
||||
val reference = element.getReference() as? JetReference ?: return listOf()
|
||||
|
||||
val descriptors = reference.resolveToDescriptors()
|
||||
val descriptors = reference.resolveToDescriptors((element as JetElement).analyze()) //TODO: we could use partial body resolve for all references together
|
||||
//check whether this reference is unambiguous
|
||||
if (reference !is JetMultiReference<*> && descriptors.size() > 1) return listOf()
|
||||
|
||||
@@ -231,7 +231,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Kotlin
|
||||
private fun createReferenceToRestoreData(element: JetElement, refData: KotlinReferenceData): ReferenceToRestoreData? {
|
||||
val reference = element.getReference() as? JetReference ?: return null
|
||||
val referencedDescriptors = try {
|
||||
reference.resolveToDescriptors()
|
||||
reference.resolveToDescriptors(element.analyze()) //TODO: we could use partial body resolve for all references together
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
LOG.error("Failed to analyze reference (${element.getText()}) after copy paste", e)
|
||||
|
||||
@@ -92,9 +92,8 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
}
|
||||
}
|
||||
|
||||
protected val bindingContext: BindingContext? = expression?.let { resolutionFacade.analyze(it, BodyResolveMode.PARTIAL_FOR_COMPLETION) }
|
||||
protected val inDescriptor: DeclarationDescriptor? = expression?.let { bindingContext!!.get(BindingContext.RESOLUTION_SCOPE, it)?.getContainingDeclaration() }
|
||||
|
||||
protected val bindingContext: BindingContext = resolutionFacade.analyze(position.getParent() as JetElement, BodyResolveMode.PARTIAL_FOR_COMPLETION)
|
||||
protected val inDescriptor: DeclarationDescriptor? = expression?.let { bindingContext.get(BindingContext.RESOLUTION_SCOPE, it)?.getContainingDeclaration() }
|
||||
|
||||
private fun singleCharPattern(char: Char): CharPattern {
|
||||
return StandardPatterns.character().with(
|
||||
@@ -130,14 +129,13 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
|
||||
protected val prefixMatcher: PrefixMatcher = this.resultSet.getPrefixMatcher()
|
||||
|
||||
protected val referenceVariantsHelper: ReferenceVariantsHelper?
|
||||
= if (bindingContext != null) ReferenceVariantsHelper(bindingContext) { isVisibleDescriptor(it) } else null
|
||||
protected val referenceVariantsHelper: ReferenceVariantsHelper = ReferenceVariantsHelper(bindingContext) { isVisibleDescriptor(it) }
|
||||
|
||||
protected val lookupElementFactory: LookupElementFactory = run {
|
||||
val receiverTypes = if (reference != null) {
|
||||
val expression = reference.expression
|
||||
val (receivers, callType) = referenceVariantsHelper!!.getReferenceVariantsReceivers(expression)
|
||||
val dataFlowInfo = bindingContext!!.getDataFlowInfo(expression)
|
||||
val (receivers, callType) = referenceVariantsHelper.getReferenceVariantsReceivers(expression)
|
||||
val dataFlowInfo = bindingContext.getDataFlowInfo(expression)
|
||||
var receiverTypes = receivers.flatMap {
|
||||
SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(it, bindingContext, moduleDescriptor, dataFlowInfo)
|
||||
}
|
||||
@@ -165,7 +163,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
}
|
||||
|
||||
protected val indicesHelper: KotlinIndicesHelper
|
||||
get() = KotlinIndicesHelper(project, resolutionFacade, bindingContext!!, searchScope, moduleDescriptor) { isVisibleDescriptor(it) }
|
||||
get() = KotlinIndicesHelper(project, resolutionFacade, bindingContext, searchScope, moduleDescriptor) { isVisibleDescriptor(it) }
|
||||
|
||||
protected fun isVisibleDescriptor(descriptor: DeclarationDescriptor): Boolean {
|
||||
if (descriptor is DeclarationDescriptorWithVisibility && inDescriptor != null) {
|
||||
@@ -194,7 +192,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
private var alreadyAddedDescriptors: Collection<DeclarationDescriptor> by Delegates.notNull()
|
||||
|
||||
protected fun getReferenceVariants(kindFilter: DescriptorKindFilter, runtimeReceiverType: Boolean): Collection<DeclarationDescriptor> {
|
||||
val descriptors = referenceVariantsHelper!!.getReferenceVariants(reference!!.expression, kindFilter, runtimeReceiverType, prefixMatcher.asNameFilter())
|
||||
val descriptors = referenceVariantsHelper.getReferenceVariants(reference!!.expression, kindFilter, runtimeReceiverType, prefixMatcher.asNameFilter())
|
||||
if (!runtimeReceiverType) {
|
||||
if (position.getContainingFile() is JetCodeFragment) {
|
||||
alreadyAddedDescriptors = descriptors
|
||||
@@ -229,7 +227,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
|
||||
protected fun addAllClasses(kindFilter: (ClassKind) -> Boolean) {
|
||||
AllClassesCompletion(
|
||||
parameters, lookupElementFactory, resolutionFacade, bindingContext!!, moduleDescriptor,
|
||||
parameters, lookupElementFactory, resolutionFacade, bindingContext, moduleDescriptor,
|
||||
searchScope, prefixMatcher, kindFilter, { isVisibleDescriptor(it) }
|
||||
).collect(collector)
|
||||
}
|
||||
@@ -311,7 +309,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
// if "this" is parsed correctly in the current context - insert it and all this@xxx items
|
||||
"this" -> {
|
||||
if (expression != null) {
|
||||
collector.addElements(thisExpressionItems(bindingContext!!, expression, prefix).map { it.factory() })
|
||||
collector.addElements(thisExpressionItems(bindingContext, expression, prefix).map { it.factory() })
|
||||
}
|
||||
else {
|
||||
// for completion in secondary constructor delegation call
|
||||
@@ -322,7 +320,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
// if "return" is parsed correctly in the current context - insert it and all return@xxx items
|
||||
"return" -> {
|
||||
if (expression != null) {
|
||||
collector.addElements(returnExpressionItems(bindingContext!!, expression))
|
||||
collector.addElements(returnExpressionItems(bindingContext, expression))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,7 +349,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
}
|
||||
}
|
||||
|
||||
NamedParametersCompletion.complete(position, collector)
|
||||
NamedParametersCompletion.complete(position, collector, bindingContext)
|
||||
}
|
||||
|
||||
private object NonAnnotationClassifierExclude : DescriptorKindExclude {
|
||||
@@ -400,7 +398,7 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
||||
if (expression != null) {
|
||||
val mapper = ToFromOriginalFileMapper(parameters.getOriginalFile() as JetFile, position.getContainingFile() as JetFile, parameters.getOffset())
|
||||
val completion = SmartCompletion(expression, resolutionFacade, moduleDescriptor,
|
||||
bindingContext!!, { isVisibleDescriptor(it) }, inDescriptor, prefixMatcher, originalSearchScope,
|
||||
bindingContext, { isVisibleDescriptor(it) }, inDescriptor, prefixMatcher, originalSearchScope,
|
||||
mapper, lookupElementFactory)
|
||||
val result = completion.execute()
|
||||
if (result != null) {
|
||||
|
||||
@@ -16,30 +16,31 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.completion
|
||||
|
||||
import org.jetbrains.kotlin.psi.JetValueArgument
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.psi.JetCallElement
|
||||
import org.jetbrains.kotlin.idea.references.JetReference
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import org.jetbrains.kotlin.idea.JetIcons
|
||||
import org.jetbrains.kotlin.idea.quickfix.QuickFixUtil
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.psi.filters.AndFilter
|
||||
import org.jetbrains.kotlin.psi.JetValueArgumentName
|
||||
import com.intellij.psi.filters.position.ParentElementFilter
|
||||
import com.intellij.psi.filters.OrFilter
|
||||
import com.intellij.psi.filters.ClassFilter
|
||||
import org.jetbrains.kotlin.idea.util.FirstChildInParentFilter
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.codeInsight.completion.InsertHandler
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.filters.AndFilter
|
||||
import com.intellij.psi.filters.ClassFilter
|
||||
import com.intellij.psi.filters.OrFilter
|
||||
import com.intellij.psi.filters.position.ParentElementFilter
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.JetIcons
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
||||
import org.jetbrains.kotlin.idea.quickfix.QuickFixUtil
|
||||
import org.jetbrains.kotlin.idea.references.JetReference
|
||||
import org.jetbrains.kotlin.idea.util.FirstChildInParentFilter
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.JetCallElement
|
||||
import org.jetbrains.kotlin.psi.JetValueArgument
|
||||
import org.jetbrains.kotlin.psi.JetValueArgumentName
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
object NamedParametersCompletion {
|
||||
private val positionFilter = AndFilter(
|
||||
@@ -68,7 +69,7 @@ object NamedParametersCompletion {
|
||||
return false
|
||||
}
|
||||
|
||||
public fun complete(position: PsiElement, collector: LookupElementsCollector) {
|
||||
public fun complete(position: PsiElement, collector: LookupElementsCollector, bindingContext: BindingContext) {
|
||||
if (!positionFilter.isAcceptable(position, position)) return
|
||||
|
||||
val valueArgument = position.getStrictParentOfType<JetValueArgument>()!!
|
||||
@@ -78,7 +79,7 @@ object NamedParametersCompletion {
|
||||
|
||||
val callReference = callSimpleName.getReference() as JetReference
|
||||
|
||||
val functionDescriptors = callReference.resolveToDescriptors().map { it as? FunctionDescriptor }.filterNotNull()
|
||||
val functionDescriptors = callReference.resolveToDescriptors(bindingContext).map { it as? FunctionDescriptor }.filterNotNull()
|
||||
|
||||
for (funDescriptor in functionDescriptors) {
|
||||
if (!funDescriptor.hasStableParameterNames()) continue
|
||||
|
||||
@@ -182,19 +182,15 @@ public class KotlinImportOptimizer() : ImportOptimizer {
|
||||
override fun visitPackageDirective(directive: JetPackageDirective) {
|
||||
}
|
||||
|
||||
|
||||
private fun JetElement.classForCompanionObjectReference(): ClassDescriptor? {
|
||||
return analyze()[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, this as? JetReferenceExpression]
|
||||
}
|
||||
|
||||
override fun visitJetElement(element: JetElement) {
|
||||
val reference = element.getReference()
|
||||
if (reference is JetReference) {
|
||||
val referencedName = (element as? JetNameReferenceExpression)?.getReferencedNameAsName() //TODO: other types of references
|
||||
|
||||
val bindingContext = element.analyze()
|
||||
//class qualifiers that refer to companion objects should be considered (containing) class references
|
||||
val targets = element.classForCompanionObjectReference()?.let { listOf(it) }
|
||||
?: reference.resolveToDescriptors()
|
||||
val targets = bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, element as? JetReferenceExpression]?.let { listOf(it) }
|
||||
?: reference.resolveToDescriptors(bindingContext)
|
||||
for (target in targets) {
|
||||
if (!target.canBeReferencedViaImport()) continue
|
||||
if (target is PackageViewDescriptor && target.getFqName().parent() == FqName.ROOT) continue // no need to import top-level packages
|
||||
|
||||
+8
-6
@@ -20,16 +20,18 @@ import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.refactoring.rename.RenameProcessor
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.idea.JetBundle
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.references.JetReference
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.JetBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.references.JetReference
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
public class ReplaceExplicitFunctionLiteralParamWithItIntention() : PsiElementBaseIntentionAction() {
|
||||
override fun invoke(project: Project, editor: Editor, element: PsiElement) {
|
||||
@@ -73,7 +75,7 @@ public class ReplaceExplicitFunctionLiteralParamWithItIntention() : PsiElementBa
|
||||
}
|
||||
is JetSimpleNameExpression -> {
|
||||
val reference = expression.getReference() as JetReference?
|
||||
val variableDescriptor = reference?.resolveToDescriptors()?.firstOrNull() as? VariableDescriptor?
|
||||
val variableDescriptor = reference?.resolveToDescriptors(expression.analyze(BodyResolveMode.PARTIAL))?.firstOrNull() as? VariableDescriptor?
|
||||
if (variableDescriptor != null) {
|
||||
val containingDescriptor = variableDescriptor.getContainingDeclaration()
|
||||
if (containingDescriptor is AnonymousFunctionDescriptor) {
|
||||
|
||||
+11
-10
@@ -22,24 +22,25 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.idea.JetBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.references.JetReference
|
||||
import org.jetbrains.kotlin.psi.JetFunctionLiteral
|
||||
import org.jetbrains.kotlin.psi.JetFunctionLiteralExpression
|
||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.idea.JetBundle
|
||||
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.JetFunctionLiteral
|
||||
import org.jetbrains.kotlin.idea.references.JetReference
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
public class ReplaceItWithExplicitFunctionLiteralParamIntention() : PsiElementBaseIntentionAction() {
|
||||
override fun invoke(project: Project, editor: Editor, element: PsiElement) {
|
||||
val simpleNameExpression = element.getStrictParentOfType<JetSimpleNameExpression>()!!
|
||||
|
||||
val simpleNameReference = simpleNameExpression.getReference() as JetReference?
|
||||
val target = simpleNameReference?.resolveToDescriptors()?.first()!!
|
||||
val target = simpleNameReference?.resolveToDescriptors(simpleNameExpression.analyze(BodyResolveMode.PARTIAL))?.first()!!
|
||||
|
||||
val funcExpr = DescriptorToSourceUtils.descriptorToDeclaration(target.getContainingDeclaration()!!) as JetFunctionLiteral
|
||||
|
||||
@@ -74,9 +75,9 @@ public class ReplaceItWithExplicitFunctionLiteralParamIntention() : PsiElementBa
|
||||
return false
|
||||
}
|
||||
|
||||
val bindingContext = simpleNameExpression.analyze()
|
||||
val bindingContext = simpleNameExpression.analyze(BodyResolveMode.PARTIAL)
|
||||
val reference = simpleNameExpression.getReference() as JetReference?
|
||||
val simpleNameTarget = reference?.resolveToDescriptors()?.firstOrNull() as? ValueParameterDescriptor?
|
||||
val simpleNameTarget = reference?.resolveToDescriptors(bindingContext)?.firstOrNull() as? ValueParameterDescriptor?
|
||||
if (simpleNameTarget == null || bindingContext.get(BindingContext.AUTO_CREATED_IT, simpleNameTarget) != true) {
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user