[Analysis API] Add KtFe10ReferenceResolutionHelper and ...
Make implementation of KtFe10XXXReference follow the old descriptor-based implementation as closely as possible.
This commit is contained in:
committed by
Ilya Kirillov
parent
b5139c958b
commit
0803ab0d0b
+10
-11
@@ -6,22 +6,21 @@
|
|||||||
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtCallableSymbol
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.references.KtArrayAccessReference
|
import org.jetbrains.kotlin.idea.references.KtArrayAccessReference
|
||||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
import org.jetbrains.kotlin.psi.KtImportAlias
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class KtFe10ArrayAccessReference(expression: KtArrayAccessExpression) : KtArrayAccessReference(expression), KtFe10Reference {
|
class KtFe10ArrayAccessReference(expression: KtArrayAccessExpression) : KtArrayAccessReference(expression), KtFe10Reference {
|
||||||
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
|
override fun isReferenceToImportAlias(alias: KtImportAlias): Boolean {
|
||||||
require(this is KtFe10AnalysisSession)
|
return super<KtFe10Reference>.isReferenceToImportAlias(alias)
|
||||||
|
}
|
||||||
|
|
||||||
val bindingContext = analysisContext.analyze(expression, AnalysisMode.PARTIAL)
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
val descriptor = expression.getResolvedCall(bindingContext)?.resultingDescriptor
|
val getFunctionDescriptor = context[BindingContext.INDEXED_LVALUE_GET, expression]?.candidateDescriptor
|
||||||
return listOfNotNull(descriptor?.toKtCallableSymbol(analysisContext))
|
val setFunctionDescriptor = context[BindingContext.INDEXED_LVALUE_SET, expression]?.candidateDescriptor
|
||||||
|
return listOfNotNull(getFunctionDescriptor, setFunctionDescriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+8
-10
@@ -5,24 +5,22 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtCallableSymbol
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.references.KtCollectionLiteralReference
|
import org.jetbrains.kotlin.idea.references.KtCollectionLiteralReference
|
||||||
import org.jetbrains.kotlin.psi.KtCollectionLiteralExpression
|
import org.jetbrains.kotlin.psi.KtCollectionLiteralExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtImportAlias
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class KtFe10CollectionLiteralReference(
|
class KtFe10CollectionLiteralReference(
|
||||||
expression: KtCollectionLiteralExpression
|
expression: KtCollectionLiteralExpression
|
||||||
) : KtCollectionLiteralReference(expression), KtFe10Reference {
|
) : KtCollectionLiteralReference(expression), KtFe10Reference {
|
||||||
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
require(this is KtFe10AnalysisSession)
|
val resolvedCall = context[BindingContext.COLLECTION_LITERAL_CALL, element]
|
||||||
|
return listOfNotNull(resolvedCall?.resultingDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
val bindingContext = analysisContext.analyze(expression, AnalysisMode.PARTIAL)
|
override fun isReferenceToImportAlias(alias: KtImportAlias): Boolean {
|
||||||
val descriptor = bindingContext[BindingContext.COLLECTION_LITERAL_CALL, expression]?.resultingDescriptor
|
return super<KtFe10Reference>.isReferenceToImportAlias(alias)
|
||||||
return listOfNotNull(descriptor?.toKtCallableSymbol(analysisContext))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-11
@@ -5,24 +5,19 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtCallableSymbol
|
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.references.KtConstructorDelegationReference
|
import org.jetbrains.kotlin.idea.references.KtConstructorDelegationReference
|
||||||
import org.jetbrains.kotlin.psi.KtConstructorDelegationReferenceExpression
|
import org.jetbrains.kotlin.psi.KtConstructorDelegationReferenceExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
import org.jetbrains.kotlin.psi.KtImportAlias
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
|
||||||
|
|
||||||
class KtFe10ConstructorDelegationReference(
|
class KtFe10ConstructorDelegationReference(
|
||||||
expression: KtConstructorDelegationReferenceExpression
|
expression: KtConstructorDelegationReferenceExpression
|
||||||
) : KtConstructorDelegationReference(expression), KtFe10Reference {
|
) : KtConstructorDelegationReference(expression), KtFe10Reference {
|
||||||
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
|
override fun getTargetDescriptors(context: BindingContext) = expression.getReferenceTargets(context)
|
||||||
require(this is KtFe10AnalysisSession)
|
|
||||||
|
|
||||||
val bindingContext = analysisContext.analyze(expression, AnalysisMode.PARTIAL)
|
override fun isReferenceToImportAlias(alias: KtImportAlias): Boolean {
|
||||||
val descriptor = expression.getResolvedCall(bindingContext)?.resultingDescriptor
|
return super<KtFe10Reference>.isReferenceToImportAlias(alias)
|
||||||
return listOfNotNull(descriptor?.toKtCallableSymbol(analysisContext))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+28
-10
@@ -5,24 +5,42 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import com.intellij.openapi.util.TextRange
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtCallableSymbol
|
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10ReferenceResolutionHelper
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
import org.jetbrains.kotlin.analysis.api.tokens.HackToForceAllowRunningAnalyzeOnEDT
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
|
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
|
||||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
|
||||||
|
import org.jetbrains.kotlin.psi.KtImportAlias
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class KtFe10DestructuringDeclarationEntry(
|
class KtFe10DestructuringDeclarationEntry(
|
||||||
element: KtDestructuringDeclarationEntry
|
element: KtDestructuringDeclarationEntry
|
||||||
) : KtDestructuringDeclarationReference(element), KtFe10Reference {
|
) : KtDestructuringDeclarationReference(element), KtFe10Reference {
|
||||||
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
check(this is KtFe10AnalysisSession)
|
return listOfNotNull(
|
||||||
|
context[BindingContext.VARIABLE, element],
|
||||||
|
context[BindingContext.COMPONENT_RESOLVED_CALL, element]?.candidateDescriptor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
val bindingContext = analysisContext.analyze(element, AnalysisMode.PARTIAL)
|
override fun resolve() = multiResolve(false).asSequence()
|
||||||
val descriptor = bindingContext[BindingContext.COMPONENT_RESOLVED_CALL, element]?.resultingDescriptor
|
.map { it.element }
|
||||||
return listOfNotNull(descriptor?.toKtCallableSymbol(analysisContext))
|
.firstOrNull { it is KtDestructuringDeclarationEntry }
|
||||||
|
|
||||||
|
override fun getRangeInElement() = TextRange(0, element.textLength)
|
||||||
|
|
||||||
|
override fun isReferenceToImportAlias(alias: KtImportAlias): Boolean {
|
||||||
|
return super<KtFe10Reference>.isReferenceToImportAlias(alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(HackToForceAllowRunningAnalyzeOnEDT::class)
|
||||||
|
override fun canRename(): Boolean {
|
||||||
|
val bindingContext = KtFe10ReferenceResolutionHelper.getInstance().partialAnalyze(element) //TODO: should it use full body resolve?
|
||||||
|
return resolveToDescriptors(bindingContext).all {
|
||||||
|
it is CallableMemberDescriptor && it.kind == CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-12
@@ -5,26 +5,29 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtCallableSymbol
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.references.KtForLoopInReference
|
import org.jetbrains.kotlin.idea.references.KtForLoopInReference
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtImportAlias
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class KtFe10ForLoopInReference(expression: KtForExpression) : KtForLoopInReference(expression), KtFe10Reference {
|
class KtFe10ForLoopInReference(expression: KtForExpression) : KtForLoopInReference(expression), KtFe10Reference {
|
||||||
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
|
|
||||||
check(this is KtFe10AnalysisSession)
|
|
||||||
|
|
||||||
val loopRange = element.loopRange ?: return emptyList()
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
val bindingContext = analysisContext.analyze(loopRange)
|
val loopRange = expression.loopRange ?: return emptyList()
|
||||||
|
return LOOP_RANGE_KEYS.mapNotNull { key -> context.get(key, loopRange)?.candidateDescriptor }
|
||||||
|
}
|
||||||
|
|
||||||
return listOf(
|
companion object {
|
||||||
|
private val LOOP_RANGE_KEYS = arrayOf(
|
||||||
BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL,
|
BindingContext.LOOP_RANGE_ITERATOR_RESOLVED_CALL,
|
||||||
BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL,
|
BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL,
|
||||||
BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL
|
BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL
|
||||||
).mapNotNull { slice -> bindingContext[slice, loopRange]?.resultingDescriptor?.toKtCallableSymbol(analysisContext) }
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isReferenceToImportAlias(alias: KtImportAlias): Boolean {
|
||||||
|
return super<KtFe10Reference>.isReferenceToImportAlias(alias)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+13
-15
@@ -5,35 +5,33 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtCallableSymbol
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference
|
import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference
|
||||||
import org.jetbrains.kotlin.psi.Call
|
import org.jetbrains.kotlin.psi.Call
|
||||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtImportAlias
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.getCall
|
import org.jetbrains.kotlin.resolve.calls.util.getCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
||||||
|
|
||||||
class KtFe10InvokeFunctionReference(expression: KtCallExpression) : KtInvokeFunctionReference(expression), KtFe10Reference {
|
class KtFe10InvokeFunctionReference(expression: KtCallExpression) : KtInvokeFunctionReference(expression), KtFe10Reference {
|
||||||
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
|
|
||||||
require(this is KtFe10AnalysisSession)
|
|
||||||
|
|
||||||
val bindingContext = analysisContext.analyze(expression, AnalysisMode.PARTIAL)
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
val call = expression.getCall(bindingContext)
|
val call = element.getCall(context)
|
||||||
val resolvedCall = call.getResolvedCall(bindingContext)
|
val resolvedCall = call.getResolvedCall(context)
|
||||||
val descriptors = when {
|
return when {
|
||||||
resolvedCall is VariableAsFunctionResolvedCall ->
|
resolvedCall is VariableAsFunctionResolvedCall ->
|
||||||
setOf((resolvedCall as VariableAsFunctionResolvedCall).functionCall.resultingDescriptor)
|
setOf<DeclarationDescriptor>((resolvedCall as VariableAsFunctionResolvedCall).functionCall.candidateDescriptor)
|
||||||
call != null && resolvedCall != null && call.callType == Call.CallType.INVOKE ->
|
call != null && resolvedCall != null && call.callType == Call.CallType.INVOKE ->
|
||||||
setOf(resolvedCall.resultingDescriptor)
|
setOf<DeclarationDescriptor>(resolvedCall.candidateDescriptor)
|
||||||
else ->
|
else ->
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
return descriptors.mapNotNull { it.toKtCallableSymbol(analysisContext) }
|
}
|
||||||
|
|
||||||
|
override fun isReferenceToImportAlias(alias: KtImportAlias): Boolean {
|
||||||
|
return super<KtFe10Reference>.isReferenceToImportAlias(alias)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-23
@@ -5,39 +5,31 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtCallableSymbol
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.accessors
|
||||||
import org.jetbrains.kotlin.idea.references.KtPropertyDelegationMethodsReference
|
import org.jetbrains.kotlin.idea.references.KtPropertyDelegationMethodsReference
|
||||||
|
import org.jetbrains.kotlin.psi.KtImportAlias
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class KtFe10PropertyDelegationMethodsReference(
|
class KtFe10PropertyDelegationMethodsReference(
|
||||||
expression: KtPropertyDelegate
|
expression: KtPropertyDelegate
|
||||||
) : KtPropertyDelegationMethodsReference(expression), KtFe10Reference {
|
) : KtPropertyDelegationMethodsReference(expression), KtFe10Reference {
|
||||||
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
|
|
||||||
require(this is KtFe10AnalysisSession)
|
|
||||||
|
|
||||||
val property = expression.parent as? KtProperty
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
if (property == null || property.delegate !== element) {
|
val property = expression.getStrictParentOfType<KtProperty>() ?: return emptyList()
|
||||||
return emptyList()
|
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, property] as? VariableDescriptorWithAccessors
|
||||||
}
|
?: return emptyList()
|
||||||
|
return descriptor.accessors.mapNotNull { accessor ->
|
||||||
|
context.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, accessor)?.candidateDescriptor
|
||||||
|
} + listOfNotNull(context.get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, descriptor)?.candidateDescriptor)
|
||||||
|
}
|
||||||
|
|
||||||
val bindingContext = analysisContext.analyze(property)
|
override fun isReferenceToImportAlias(alias: KtImportAlias): Boolean {
|
||||||
val propertyDescriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, property]
|
return super<KtFe10Reference>.isReferenceToImportAlias(alias)
|
||||||
|
|
||||||
if (propertyDescriptor is PropertyDescriptor) {
|
|
||||||
return listOfNotNull(propertyDescriptor.getter, propertyDescriptor.setter)
|
|
||||||
.mapNotNull { accessor ->
|
|
||||||
val descriptor = bindingContext[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, accessor]?.resultingDescriptor
|
|
||||||
descriptor?.toKtCallableSymbol(analysisContext)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return emptyList()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+62
-15
@@ -6,33 +6,80 @@
|
|||||||
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
package org.jetbrains.kotlin.analysis.api.descriptors.references
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import com.intellij.util.SmartList
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtSymbol
|
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10ReferenceResolutionHelper
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
|
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.plugin.references.SimpleNameReferenceExtension
|
||||||
import org.jetbrains.kotlin.psi.KtImportAlias
|
import org.jetbrains.kotlin.psi.KtImportAlias
|
||||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getImportableDescriptor
|
||||||
|
|
||||||
|
|
||||||
class KtFe10SimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleNameReference(expression), KtFe10Reference {
|
class KtFe10SimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleNameReference(expression), KtFe10Reference {
|
||||||
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
|
|
||||||
require(this is KtFe10AnalysisSession)
|
|
||||||
|
|
||||||
val bindingContext = analysisContext.analyze(expression, AnalysisMode.PARTIAL)
|
override fun canBeReferenceTo(candidateTarget: PsiElement): Boolean {
|
||||||
|
return element.containingFile == candidateTarget.containingFile ||
|
||||||
val descriptor = bindingContext[BindingContext.REFERENCE_TARGET, expression]
|
KtFe10ReferenceResolutionHelper.getInstance().isInProjectOrLibSource(element, includeScriptsOutsideSourceRoots = true)
|
||||||
?: expression.getResolvedCall(bindingContext)?.resultingDescriptor
|
|
||||||
|
|
||||||
return listOfNotNull(descriptor?.toKtSymbol(analysisContext))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isReferenceToViaExtension(element: PsiElement): Boolean = false
|
override fun isReferenceToImportAlias(alias: KtImportAlias): Boolean {
|
||||||
|
return super<KtFe10Reference>.isReferenceToImportAlias(alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
|
||||||
|
return SmartList<DeclarationDescriptor>().apply {
|
||||||
|
// Replace Java property with its accessor(s)
|
||||||
|
for (descriptor in expression.getReferenceTargets(context)) {
|
||||||
|
val sizeBefore = size
|
||||||
|
|
||||||
|
if (descriptor !is JavaPropertyDescriptor) {
|
||||||
|
add(descriptor)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val readWriteAccess = expression.readWriteAccess(true)
|
||||||
|
descriptor.getter?.let {
|
||||||
|
if (readWriteAccess.isRead) add(it)
|
||||||
|
}
|
||||||
|
descriptor.setter?.let {
|
||||||
|
if (readWriteAccess.isWrite) add(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == sizeBefore) {
|
||||||
|
add(descriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isReferenceToViaExtension(element: PsiElement): Boolean {
|
||||||
|
for (extension in element.project.extensionArea.getExtensionPoint(SimpleNameReferenceExtension.EP_NAME).extensions) {
|
||||||
|
if (extension.isReferenceTo(this, element)) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
override fun getImportAlias(): KtImportAlias? {
|
override fun getImportAlias(): KtImportAlias? {
|
||||||
|
fun DeclarationDescriptor.unwrap() = if (this is ImportedFromObjectCallableDescriptor<*>) callableFromObject else this
|
||||||
|
|
||||||
|
val name = element.getReferencedName()
|
||||||
|
val file = element.containingKtFile
|
||||||
|
val importDirective = file.findImportByAlias(name) ?: return null
|
||||||
|
val fqName = importDirective.importedFqName ?: return null
|
||||||
|
val helper = KtFe10ReferenceResolutionHelper.getInstance()
|
||||||
|
val importedDescriptors = helper.resolveImportReference(file, fqName).map { it.unwrap() }
|
||||||
|
if (getTargetDescriptors(helper.partialAnalyze(element)).any {
|
||||||
|
it.unwrap().getImportableDescriptor() in importedDescriptors
|
||||||
|
}) {
|
||||||
|
return importDirective.alias
|
||||||
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+57
-23
@@ -5,38 +5,72 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api.descriptors.references.base
|
package org.jetbrains.kotlin.analysis.api.descriptors.references.base
|
||||||
|
|
||||||
|
import com.intellij.psi.JavaPsiFacade
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiElementResolveResult
|
import com.intellij.psi.PsiElementResolveResult
|
||||||
import com.intellij.psi.ResolveResult
|
import com.intellij.psi.ResolveResult
|
||||||
import com.intellij.psi.impl.source.resolve.ResolveCache
|
import com.intellij.psi.impl.source.resolve.ResolveCache
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisOnEdt
|
import org.jetbrains.kotlin.analysis.api.descriptors.utils.DescriptorToSourceUtilsIde
|
||||||
import org.jetbrains.kotlin.analysis.api.analyze
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
|
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
|
||||||
import org.jetbrains.kotlin.analysis.api.lifetime.allowAnalysisOnEdt
|
|
||||||
import org.jetbrains.kotlin.idea.references.AbstractKtReference
|
import org.jetbrains.kotlin.idea.references.AbstractKtReference
|
||||||
import org.jetbrains.kotlin.idea.references.KtReference
|
import org.jetbrains.kotlin.idea.references.KtReference
|
||||||
import org.jetbrains.kotlin.load.kotlin.toSourceElement
|
|
||||||
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
import java.util.*
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
|
||||||
|
|
||||||
object KtFe10PolyVariantResolver : ResolveCache.PolyVariantResolver<KtReference> {
|
object KtFe10PolyVariantResolver : ResolveCache.PolyVariantResolver<KtReference> {
|
||||||
@OptIn(KtAllowAnalysisOnEdt::class)
|
class KotlinResolveResult(element: PsiElement) : PsiElementResolveResult(element)
|
||||||
override fun resolve(reference: KtReference, incompleteCode: Boolean): Array<ResolveResult> {
|
|
||||||
require(reference is AbstractKtReference<*>) { "reference should be AbstractKtReference, but was ${reference::class}" }
|
private fun resolveToPsiElements(ref: KtFe10Reference): Collection<PsiElement> {
|
||||||
return allowAnalysisOnEdt {
|
require(ref is AbstractKtReference<*>) { "reference should be AbstractKtReference, but was ${ref::class}" }
|
||||||
val expression = reference.expression
|
val bindingContext = KtFe10ReferenceResolutionHelper.getInstance().partialAnalyze(ref.expression)
|
||||||
analyze(reference.expression) {
|
if (bindingContext == BindingContext.EMPTY) return emptySet()
|
||||||
val analysisSession = this as KtFe10AnalysisSession
|
return resolveToPsiElements(ref, bindingContext, ref.getTargetDescriptors(bindingContext))
|
||||||
val bindingContext = analysisSession.analysisContext.analyze(expression, AnalysisMode.PARTIAL)
|
}
|
||||||
val descriptor = when (expression) {
|
|
||||||
is KtReferenceExpression -> bindingContext[BindingContext.REFERENCE_TARGET, expression]
|
private fun resolveToPsiElements(
|
||||||
else -> expression.getResolvedCall(bindingContext)?.resultingDescriptor
|
ref: KtFe10Reference,
|
||||||
}
|
context: BindingContext,
|
||||||
val source = descriptor?.toSourceElement?.getPsi()
|
targetDescriptors: Collection<DeclarationDescriptor>
|
||||||
if (source != null) arrayOf(PsiElementResolveResult(source)) else emptyArray()
|
): Collection<PsiElement> {
|
||||||
}
|
if (targetDescriptors.isNotEmpty()) {
|
||||||
|
return targetDescriptors.flatMap { target -> resolveToPsiElements(ref, target) }.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val labelTargets = getLabelTargets(ref, context)
|
||||||
|
if (labelTargets != null) {
|
||||||
|
return labelTargets
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.emptySet()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveToPsiElements(
|
||||||
|
ref: KtFe10Reference,
|
||||||
|
targetDescriptor: DeclarationDescriptor
|
||||||
|
): Collection<PsiElement> = if (targetDescriptor is PackageViewDescriptor) {
|
||||||
|
val psiFacade = JavaPsiFacade.getInstance(ref.element.project)
|
||||||
|
val fqName = targetDescriptor.fqName.asString()
|
||||||
|
listOfNotNull(psiFacade.findPackage(fqName))
|
||||||
|
} else {
|
||||||
|
DescriptorToSourceUtilsIde.getAllDeclarations(ref.element.project, targetDescriptor, ref.element.resolveScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLabelTargets(ref: KtFe10Reference, context: BindingContext): Collection<PsiElement>? {
|
||||||
|
val reference = ref.element as? KtReferenceExpression ?: return null
|
||||||
|
val labelTarget = context[BindingContext.LABEL_TARGET, reference]
|
||||||
|
if (labelTarget != null) {
|
||||||
|
return listOf(labelTarget)
|
||||||
|
}
|
||||||
|
|
||||||
|
return context[BindingContext.AMBIGUOUS_LABEL_TARGET, reference]
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Old impl from IDE side has this logic wrapped inside runWithCancellationCheck. Figure out what we should do here.
|
||||||
|
override fun resolve(ref: KtReference, incompleteCode: Boolean): Array<ResolveResult> {
|
||||||
|
require(ref is KtFe10Reference) { "reference should be KtFe10Reference, but was ${ref::class}" }
|
||||||
|
val resolveToPsiElements = resolveToPsiElements(ref)
|
||||||
|
return resolveToPsiElements.map { KotlinResolveResult(it) }.toTypedArray()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+46
@@ -5,11 +5,57 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api.descriptors.references.base
|
package org.jetbrains.kotlin.analysis.api.descriptors.references.base
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
import com.intellij.psi.impl.source.resolve.ResolveCache
|
import com.intellij.psi.impl.source.resolve.ResolveCache
|
||||||
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.KtSymbolBasedReference
|
import org.jetbrains.kotlin.analysis.api.KtSymbolBasedReference
|
||||||
|
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
||||||
|
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtSymbol
|
||||||
|
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.references.KtReference
|
import org.jetbrains.kotlin.idea.references.KtReference
|
||||||
|
import org.jetbrains.kotlin.idea.references.unwrappedTargets
|
||||||
|
import org.jetbrains.kotlin.psi.KtConstructor
|
||||||
|
import org.jetbrains.kotlin.psi.KtImportAlias
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
interface KtFe10Reference : KtReference, KtSymbolBasedReference {
|
interface KtFe10Reference : KtReference, KtSymbolBasedReference {
|
||||||
override val resolver: ResolveCache.PolyVariantResolver<KtReference>
|
override val resolver: ResolveCache.PolyVariantResolver<KtReference>
|
||||||
get() = KtFe10PolyVariantResolver
|
get() = KtFe10PolyVariantResolver
|
||||||
|
|
||||||
|
fun resolveToDescriptors(bindingContext: BindingContext): Collection<DeclarationDescriptor> = getTargetDescriptors(bindingContext)
|
||||||
|
|
||||||
|
fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor>
|
||||||
|
|
||||||
|
fun isReferenceToImportAlias(alias: KtImportAlias): Boolean {
|
||||||
|
val importDirective = alias.importDirective ?: return false
|
||||||
|
val importedFqName = importDirective.importedFqName ?: return false
|
||||||
|
val helper = KtFe10ReferenceResolutionHelper.getInstance()
|
||||||
|
val importedDescriptors = helper.resolveImportReference(importDirective.containingKtFile, importedFqName)
|
||||||
|
val importableTargets = unwrappedTargets.mapNotNull {
|
||||||
|
when {
|
||||||
|
it is KtConstructor<*> -> it.containingClassOrObject
|
||||||
|
it is PsiMethod && it.isConstructor -> it.containingClass
|
||||||
|
else -> it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val project = element.project
|
||||||
|
val resolveScope = element.resolveScope
|
||||||
|
|
||||||
|
return importedDescriptors.any {
|
||||||
|
helper.findPsiDeclarations(it, project, resolveScope).any { declaration ->
|
||||||
|
declaration in importableTargets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
|
||||||
|
require(this is KtFe10AnalysisSession)
|
||||||
|
val bindingContext = KtFe10ReferenceResolutionHelper.getInstance().partialAnalyze(element)
|
||||||
|
return getTargetDescriptors(bindingContext).mapNotNull { descriptor ->
|
||||||
|
descriptor.toKtSymbol(analysisContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.analysis.api.descriptors.references.base
|
||||||
|
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporary helper that allows FE1.0 KtReferences to use some IDE functionality.
|
||||||
|
*/
|
||||||
|
interface KtFe10ReferenceResolutionHelper {
|
||||||
|
fun isInProjectOrLibSource(element: PsiElement, includeScriptsOutsideSourceRoots: Boolean): Boolean
|
||||||
|
|
||||||
|
fun resolveImportReference(file: KtFile, fqName: FqName): Collection<DeclarationDescriptor>
|
||||||
|
|
||||||
|
fun partialAnalyze(element: KtElement): BindingContext
|
||||||
|
|
||||||
|
fun findDecompiledDeclaration(
|
||||||
|
project: Project,
|
||||||
|
referencedDescriptor: DeclarationDescriptor,
|
||||||
|
builtInsSearchScope: GlobalSearchScope?
|
||||||
|
): KtDeclaration?
|
||||||
|
|
||||||
|
fun findPsiDeclarations(declaration: DeclarationDescriptor, project: Project, resolveScope: GlobalSearchScope): Collection<PsiElement>
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getInstance() = ApplicationManager.getApplication().getService(KtFe10ReferenceResolutionHelper::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.analysis.api.descriptors.utils
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10ReferenceResolutionHelper
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.sequenceOfLazyValues
|
||||||
|
|
||||||
|
object DescriptorToSourceUtilsIde {
|
||||||
|
// Returns PSI element for descriptor. If there are many relevant elements (e.g. it is fake override
|
||||||
|
// with multiple declarations), finds any of them. It can find declarations in builtins or decompiled code.
|
||||||
|
fun getAnyDeclaration(project: Project, descriptor: DeclarationDescriptor): PsiElement? {
|
||||||
|
return getDeclarationsStream(project, descriptor).firstOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns all PSI elements for descriptor. It can find declarations in builtins or decompiled code.
|
||||||
|
fun getAllDeclarations(
|
||||||
|
project: Project,
|
||||||
|
targetDescriptor: DeclarationDescriptor,
|
||||||
|
builtInsSearchScope: GlobalSearchScope? = null
|
||||||
|
): Collection<PsiElement> {
|
||||||
|
val result = getDeclarationsStream(project, targetDescriptor, builtInsSearchScope).toHashSet()
|
||||||
|
// filter out elements which are navigate to some other element of the result
|
||||||
|
// this is needed to avoid duplicated results for references to declaration in same library source file
|
||||||
|
return result.filter { element -> result.none { element != it && it.navigationElement == element } }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDeclarationsStream(
|
||||||
|
project: Project, targetDescriptor: DeclarationDescriptor, builtInsSearchScope: GlobalSearchScope? = null
|
||||||
|
): Sequence<PsiElement> {
|
||||||
|
val effectiveReferencedDescriptors = DescriptorToSourceUtils.getEffectiveReferencedDescriptors(targetDescriptor).asSequence()
|
||||||
|
return effectiveReferencedDescriptors.flatMap { effectiveReferenced ->
|
||||||
|
// References in library sources should be resolved to corresponding decompiled declarations,
|
||||||
|
// therefore we put both source declaration and decompiled declaration to stream, and afterwards we filter it in getAllDeclarations
|
||||||
|
sequenceOfLazyValues(
|
||||||
|
{ DescriptorToSourceUtils.getSourceFromDescriptor(effectiveReferenced) },
|
||||||
|
{ KtFe10ReferenceResolutionHelper.getInstance().findDecompiledDeclaration(project, effectiveReferenced, builtInsSearchScope) }
|
||||||
|
)
|
||||||
|
}.filterNotNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.references
|
||||||
|
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||||
|
import org.jetbrains.kotlin.resolve.references.ReferenceAccess
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.constant
|
||||||
|
|
||||||
|
interface ReadWriteAccessChecker {
|
||||||
|
fun readWriteAccessWithFullExpressionByResolve(assignment: KtBinaryExpression): Pair<ReferenceAccess, KtExpression>?
|
||||||
|
|
||||||
|
fun readWriteAccessWithFullExpression(
|
||||||
|
targetExpression: KtExpression,
|
||||||
|
useResolveForReadWrite: Boolean
|
||||||
|
): Pair<ReferenceAccess, KtExpression> {
|
||||||
|
var expression = targetExpression.getQualifiedExpressionForSelectorOrThis()
|
||||||
|
loop@ while (true) {
|
||||||
|
when (val parent = expression.parent) {
|
||||||
|
is KtParenthesizedExpression, is KtAnnotatedExpression, is KtLabeledExpression -> expression = parent as KtExpression
|
||||||
|
else -> break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val assignment = expression.getAssignmentByLHS()
|
||||||
|
if (assignment != null) {
|
||||||
|
return when (assignment.operationToken) {
|
||||||
|
KtTokens.EQ -> ReferenceAccess.WRITE to assignment
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
(if (useResolveForReadWrite) readWriteAccessWithFullExpressionByResolve(assignment) else null)
|
||||||
|
?: (ReferenceAccess.READ_WRITE to assignment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val unaryExpression = expression.parent as? KtUnaryExpression
|
||||||
|
return if (unaryExpression != null && unaryExpression.operationToken in constant { setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) })
|
||||||
|
ReferenceAccess.READ_WRITE to unaryExpression
|
||||||
|
else
|
||||||
|
ReferenceAccess.READ to expression
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getInstance(): ReadWriteAccessChecker = ApplicationManager.getApplication().getService(ReadWriteAccessChecker::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun KtExpression.readWriteAccessWithFullExpression(useResolveForReadWrite: Boolean): Pair<ReferenceAccess, KtExpression> =
|
||||||
|
ReadWriteAccessChecker.getInstance().readWriteAccessWithFullExpression(this, useResolveForReadWrite)
|
||||||
|
|
||||||
|
fun KtExpression.readWriteAccess(useResolveForReadWrite: Boolean): ReferenceAccess =
|
||||||
|
ReadWriteAccessChecker.getInstance().readWriteAccessWithFullExpression(this, useResolveForReadWrite).first
|
||||||
|
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.plugin.references
|
||||||
|
|
||||||
|
import com.intellij.openapi.extensions.ExtensionPointName
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
|
|
||||||
|
interface SimpleNameReferenceExtension {
|
||||||
|
companion object {
|
||||||
|
val EP_NAME: ExtensionPointName<SimpleNameReferenceExtension> =
|
||||||
|
ExtensionPointName.create("org.jetbrains.kotlin.simpleNameReferenceExtension")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isReferenceTo(reference: KtSimpleNameReference, element: PsiElement): Boolean
|
||||||
|
|
||||||
|
fun handleElementRename(reference: KtSimpleNameReference, psiFactory: KtPsiFactory, newElementName: String): PsiElement?
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user