[FIR IDE] Implement FIR for KotlinUsageTypeProvider
This commit is contained in:
@@ -6,214 +6,10 @@
|
||||
package org.jetbrains.kotlin.idea.findUsages
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiPackage
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum.*
|
||||
import org.jetbrains.kotlin.idea.references.*
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import com.intellij.usages.impl.rules.UsageTypeProviderEx
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
|
||||
object UsageTypeUtils {
|
||||
fun getUsageType(element: PsiElement?): UsageTypeEnum? {
|
||||
when (element) {
|
||||
is KtForExpression -> return IMPLICIT_ITERATION
|
||||
is KtDestructuringDeclarationEntry -> return READ
|
||||
is KtPropertyDelegate -> return PROPERTY_DELEGATION
|
||||
is KtStringTemplateExpression -> return USAGE_IN_STRING_LITERAL
|
||||
}
|
||||
|
||||
val refExpr = element?.getNonStrictParentOfType<KtReferenceExpression>() ?: return null
|
||||
|
||||
val context = refExpr.analyze(BodyResolveMode.PARTIAL)
|
||||
|
||||
fun getCommonUsageType(): UsageTypeEnum? = when {
|
||||
refExpr.getNonStrictParentOfType<KtImportDirective>() != null -> CLASS_IMPORT
|
||||
refExpr.getParentOfTypeAndBranch<KtCallableReferenceExpression>() { callableReference } != null -> CALLABLE_REFERENCE
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun getClassUsageType(): UsageTypeEnum? {
|
||||
if (refExpr.getNonStrictParentOfType<KtTypeProjection>() != null) return TYPE_PARAMETER
|
||||
|
||||
val property = refExpr.getNonStrictParentOfType<KtProperty>()
|
||||
if (property != null) {
|
||||
when {
|
||||
property.typeReference.isAncestor(refExpr) ->
|
||||
return if (property.isLocal) CLASS_LOCAL_VAR_DECLARATION else NON_LOCAL_PROPERTY_TYPE
|
||||
|
||||
property.receiverTypeReference.isAncestor(refExpr) ->
|
||||
return EXTENSION_RECEIVER_TYPE
|
||||
}
|
||||
}
|
||||
|
||||
val function = refExpr.getNonStrictParentOfType<KtFunction>()
|
||||
if (function != null) {
|
||||
when {
|
||||
function.typeReference.isAncestor(refExpr) ->
|
||||
return FUNCTION_RETURN_TYPE
|
||||
function.receiverTypeReference.isAncestor(refExpr) ->
|
||||
return EXTENSION_RECEIVER_TYPE
|
||||
}
|
||||
}
|
||||
|
||||
return when {
|
||||
refExpr.getParentOfTypeAndBranch<KtTypeParameter>() { extendsBound } != null || refExpr.getParentOfTypeAndBranch<KtTypeConstraint>() { boundTypeReference } != null -> TYPE_CONSTRAINT
|
||||
|
||||
refExpr is KtSuperTypeListEntry || refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry>() { typeReference } != null -> SUPER_TYPE
|
||||
|
||||
refExpr.getParentOfTypeAndBranch<KtParameter>() { typeReference } != null -> VALUE_PARAMETER_TYPE
|
||||
|
||||
refExpr.getParentOfTypeAndBranch<KtIsExpression>() { typeReference } != null || refExpr.getParentOfTypeAndBranch<KtWhenConditionIsPattern>() { typeReference } != null -> IS
|
||||
|
||||
with(refExpr.getParentOfTypeAndBranch<KtBinaryExpressionWithTypeRHS>() { right }) {
|
||||
val opType = this?.operationReference?.getReferencedNameElementType()
|
||||
opType == KtTokens.AS_KEYWORD || opType == KtTokens.AS_SAFE
|
||||
} -> CLASS_CAST_TO
|
||||
|
||||
with(refExpr.getNonStrictParentOfType<KtDotQualifiedExpression>()) {
|
||||
when {
|
||||
this == null -> {
|
||||
false
|
||||
}
|
||||
receiverExpression == refExpr -> {
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
selectorExpression == refExpr
|
||||
&& getParentOfTypeAndBranch<KtDotQualifiedExpression>(strict = true) { receiverExpression } != null
|
||||
}
|
||||
}
|
||||
} -> CLASS_OBJECT_ACCESS
|
||||
|
||||
refExpr.getParentOfTypeAndBranch<KtSuperExpression>() { superTypeQualifier } != null -> SUPER_TYPE_QUALIFIER
|
||||
|
||||
refExpr.getParentOfTypeAndBranch<KtTypeAlias> { getTypeReference() } != null -> TYPE_ALIAS
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun getVariableUsageType(): UsageTypeEnum? {
|
||||
if (refExpr.getParentOfTypeAndBranch<KtDelegatedSuperTypeEntry>() { delegateExpression } != null) return DELEGATE
|
||||
|
||||
if (refExpr.parent is KtValueArgumentName) return NAMED_ARGUMENT
|
||||
|
||||
val dotQualifiedExpression = refExpr.getNonStrictParentOfType<KtDotQualifiedExpression>()
|
||||
|
||||
if (dotQualifiedExpression != null) {
|
||||
val parent = dotQualifiedExpression.parent
|
||||
when {
|
||||
dotQualifiedExpression.receiverExpression.isAncestor(refExpr) ->
|
||||
return RECEIVER
|
||||
|
||||
parent is KtDotQualifiedExpression && parent.receiverExpression.isAncestor(refExpr) ->
|
||||
return RECEIVER
|
||||
}
|
||||
}
|
||||
|
||||
return when (refExpr.readWriteAccess(useResolveForReadWrite = true)) {
|
||||
ReferenceAccess.READ -> READ
|
||||
ReferenceAccess.WRITE, ReferenceAccess.READ_WRITE -> WRITE
|
||||
}
|
||||
}
|
||||
|
||||
fun getFunctionUsageType(descriptor: FunctionDescriptor): UsageTypeEnum? {
|
||||
when (refExpr.mainReference) {
|
||||
is KtArrayAccessReference -> {
|
||||
return when {
|
||||
context[BindingContext.INDEXED_LVALUE_GET, refExpr] != null -> IMPLICIT_GET
|
||||
context[BindingContext.INDEXED_LVALUE_SET, refExpr] != null -> IMPLICIT_SET
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
is KtInvokeFunctionReference -> return IMPLICIT_INVOKE
|
||||
}
|
||||
|
||||
return when {
|
||||
refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry>() { typeReference } != null -> SUPER_TYPE
|
||||
|
||||
descriptor is ConstructorDescriptor && refExpr.getParentOfTypeAndBranch<KtAnnotationEntry>() { typeReference } != null -> ANNOTATION
|
||||
|
||||
with(refExpr.getParentOfTypeAndBranch<KtCallExpression>() { calleeExpression }) {
|
||||
this?.calleeExpression is KtSimpleNameExpression
|
||||
} -> if (descriptor is ConstructorDescriptor) CLASS_NEW_OPERATOR else FUNCTION_CALL
|
||||
|
||||
refExpr.getParentOfTypeAndBranch<KtBinaryExpression>() { operationReference } != null || refExpr.getParentOfTypeAndBranch<KtUnaryExpression>() { operationReference } != null || refExpr.getParentOfTypeAndBranch<KtWhenConditionInRange>() { operationReference } != null -> FUNCTION_CALL
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun getPackageUsageType(): UsageTypeEnum? = when {
|
||||
refExpr.getNonStrictParentOfType<KtPackageDirective>() != null -> PACKAGE_DIRECTIVE
|
||||
refExpr.getNonStrictParentOfType<KtQualifiedExpression>() != null -> PACKAGE_MEMBER_ACCESS
|
||||
else -> getClassUsageType()
|
||||
}
|
||||
|
||||
val usageType = getCommonUsageType()
|
||||
if (usageType != null) return usageType
|
||||
|
||||
return when (val descriptor = context[BindingContext.REFERENCE_TARGET, refExpr]) {
|
||||
is ClassifierDescriptor -> when {
|
||||
// Treat object accesses as variables to simulate the old behaviour (when variables were created for objects)
|
||||
DescriptorUtils.isNonCompanionObject(descriptor) || DescriptorUtils.isEnumEntry(descriptor) -> getVariableUsageType()
|
||||
DescriptorUtils.isCompanionObject(descriptor) -> COMPANION_OBJECT_ACCESS
|
||||
else -> getClassUsageType()
|
||||
}
|
||||
is PackageViewDescriptor -> {
|
||||
if (refExpr.mainReference.resolve() is PsiPackage) getPackageUsageType() else getClassUsageType()
|
||||
}
|
||||
is VariableDescriptor -> getVariableUsageType()
|
||||
is FunctionDescriptor -> getFunctionUsageType(descriptor)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class UsageTypeEnum {
|
||||
TYPE_CONSTRAINT,
|
||||
VALUE_PARAMETER_TYPE,
|
||||
NON_LOCAL_PROPERTY_TYPE,
|
||||
FUNCTION_RETURN_TYPE,
|
||||
SUPER_TYPE,
|
||||
IS,
|
||||
CLASS_OBJECT_ACCESS,
|
||||
COMPANION_OBJECT_ACCESS,
|
||||
EXTENSION_RECEIVER_TYPE,
|
||||
SUPER_TYPE_QUALIFIER,
|
||||
TYPE_ALIAS,
|
||||
|
||||
FUNCTION_CALL,
|
||||
IMPLICIT_GET,
|
||||
IMPLICIT_SET,
|
||||
IMPLICIT_INVOKE,
|
||||
IMPLICIT_ITERATION,
|
||||
PROPERTY_DELEGATION,
|
||||
|
||||
RECEIVER,
|
||||
DELEGATE,
|
||||
|
||||
PACKAGE_DIRECTIVE,
|
||||
PACKAGE_MEMBER_ACCESS,
|
||||
|
||||
CALLABLE_REFERENCE,
|
||||
|
||||
READ,
|
||||
WRITE,
|
||||
CLASS_IMPORT,
|
||||
CLASS_LOCAL_VAR_DECLARATION,
|
||||
TYPE_PARAMETER,
|
||||
CLASS_CAST_TO,
|
||||
ANNOTATION,
|
||||
CLASS_NEW_OPERATOR,
|
||||
NAMED_ARGUMENT,
|
||||
|
||||
USAGE_IN_STRING_LITERAL
|
||||
}
|
||||
//object UsageTypeUtils {
|
||||
// fun getUsageType(element: PsiElement?): UsageTypeEnum? =
|
||||
// UsageTypeProviderEx.EP_NAME.extensions.firstIsInstance<KotlinUsageTypeProvider>().getUsageTypeEnum(element)
|
||||
//}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.findUsages
|
||||
|
||||
import com.intellij.psi.PsiPackage
|
||||
import org.jetbrains.kotlin.idea.references.KtArrayAccessReference
|
||||
import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.analyzeWithReadAction
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleReference
|
||||
|
||||
class KotlinUsageTypeProviderFirImpl : KotlinUsageTypeProvider() {
|
||||
|
||||
override fun getUsageTypeEnumByReference(refExpr: KtReferenceExpression): UsageTypeEnum? {
|
||||
|
||||
val reference = refExpr.mainReference
|
||||
check(reference is KtSimpleReference<*>) { "Reference should be KtSimpleReference but not ${reference::class}" }
|
||||
|
||||
fun getFunctionUsageType(functionSymbol: KtFunctionLikeSymbol): UsageTypeEnum? {
|
||||
when (reference) {
|
||||
is KtArrayAccessReference -> {
|
||||
TODO("FIR Implement implicit get/set")
|
||||
// return when {
|
||||
// //KtFirArrayAccessReference
|
||||
//// context[BindingContext.INDEXED_LVALUE_GET, refExpr] != null -> IMPLICIT_GET
|
||||
//// context[BindingContext.INDEXED_LVALUE_SET, refExpr] != null -> IMPLICIT_SET
|
||||
// else -> null
|
||||
// }
|
||||
}
|
||||
is KtInvokeFunctionReference -> return IMPLICIT_INVOKE
|
||||
}
|
||||
|
||||
return when {
|
||||
refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry> { typeReference } != null -> SUPER_TYPE
|
||||
|
||||
functionSymbol is KtConstructorSymbol && refExpr.getParentOfTypeAndBranch<KtAnnotationEntry> { typeReference } != null -> ANNOTATION
|
||||
|
||||
with(refExpr.getParentOfTypeAndBranch<KtCallExpression> { calleeExpression }) {
|
||||
this?.calleeExpression is KtSimpleNameExpression
|
||||
} -> if (functionSymbol is KtConstructorSymbol) CLASS_NEW_OPERATOR else FUNCTION_CALL //HLAPI resolveCall -> CallInfo ->
|
||||
|
||||
refExpr.getParentOfTypeAndBranch<KtBinaryExpression> { operationReference } != null || refExpr.getParentOfTypeAndBranch<KtUnaryExpression> { operationReference } != null || refExpr.getParentOfTypeAndBranch<KtWhenConditionInRange> { operationReference } != null -> FUNCTION_CALL
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
return analyzeWithReadAction(refExpr) {
|
||||
when (val targetElement = reference.resolveToSymbol()) {
|
||||
is KtClassOrObjectSymbol ->
|
||||
when {
|
||||
// Treat object accesses as variables to simulate the old behaviour (when variables were created for objects)
|
||||
targetElement is KtEnumEntrySymbol -> getVariableUsageType(refExpr)
|
||||
targetElement.classKind == KtClassKind.COMPANION_OBJECT -> COMPANION_OBJECT_ACCESS
|
||||
targetElement.classKind == KtClassKind.OBJECT -> getVariableUsageType(refExpr)
|
||||
else -> getClassUsageType(refExpr)
|
||||
}
|
||||
is KtPackageSymbol -> //TODO FIR Implement package symbol type
|
||||
if (targetElement is PsiPackage) getPackageUsageType(refExpr) else getClassUsageType(refExpr)
|
||||
is KtVariableSymbol -> getVariableUsageType(refExpr)
|
||||
is KtFunctionLikeSymbol -> getFunctionUsageType(targetElement)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
@@ -38,3 +38,27 @@ find.usages.tool.tip.text.disable.search.for.data.class.components.and.destructi
|
||||
find.usages.checkbox.text.fast.data.class.component.search=Fast data class component search
|
||||
find.usages.checkbox.name.expected.properties=Expected properties
|
||||
find.usages.action.text.find.usages.of=find usages of
|
||||
|
||||
find.usages.type.named.argument=Named argument
|
||||
find.usages.type.type.alias=Type alias
|
||||
find.usages.type.callable.reference=Callable reference
|
||||
find.usages.type.type.constraint=Type constraint
|
||||
find.usages.type.value.parameter.type=Parameter type
|
||||
find.usages.type.nonLocal.property.type=Class/object property type
|
||||
find.usages.type.function.return.type=Function return types
|
||||
find.usages.type.superType=Supertype
|
||||
find.usages.type.is=Target type of 'is' operation
|
||||
find.usages.type.class.object=Nested class/object
|
||||
find.usages.type.companion.object=Companion object
|
||||
find.usages.type.function.call=Function call
|
||||
find.usages.type.implicit.get=Implicit 'get'
|
||||
find.usages.type.implicit.set=Implicit 'set'
|
||||
find.usages.type.implicit.invoke=Implicit 'invoke'
|
||||
find.usages.type.implicit.iteration=Implicit iteration
|
||||
find.usages.type.property.delegation=Property delegation
|
||||
find.usages.type.extension.receiver.type=Extension receiver type
|
||||
find.usages.type.super.type.qualifier=Super type qualifier
|
||||
find.usages.type.receiver=Receiver
|
||||
find.usages.type.delegate=Delegate
|
||||
find.usages.type.packageDirective=Package directive
|
||||
find.usages.type.packageMemberAccess=Package member access
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.findUsages
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.usages.UsageTarget
|
||||
import com.intellij.usages.impl.rules.UsageType
|
||||
import com.intellij.usages.impl.rules.UsageTypeProviderEx
|
||||
import org.jetbrains.kotlin.idea.findUsages.KotlinUsageTypes.toUsageType
|
||||
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum.*
|
||||
import org.jetbrains.kotlin.idea.references.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
|
||||
abstract class KotlinUsageTypeProvider : UsageTypeProviderEx {
|
||||
|
||||
abstract fun getUsageTypeEnumByReference(refExpr: KtReferenceExpression): UsageTypeEnum?
|
||||
|
||||
private fun getUsageTypeEnum(element: PsiElement?): UsageTypeEnum? {
|
||||
when (element) {
|
||||
is KtForExpression -> return IMPLICIT_ITERATION
|
||||
is KtDestructuringDeclarationEntry -> return READ
|
||||
is KtPropertyDelegate -> return PROPERTY_DELEGATION
|
||||
is KtStringTemplateExpression -> return USAGE_IN_STRING_LITERAL
|
||||
}
|
||||
|
||||
val refExpr = element?.getNonStrictParentOfType<KtReferenceExpression>() ?: return null
|
||||
|
||||
return getCommonUsageType(refExpr) ?: getUsageTypeEnumByReference(refExpr)
|
||||
}
|
||||
|
||||
override fun getUsageType(element: PsiElement?): UsageType? = getUsageType(element, UsageTarget.EMPTY_ARRAY)
|
||||
|
||||
override fun getUsageType(element: PsiElement?, targets: Array<out UsageTarget>): UsageType? {
|
||||
val usageType = getUsageTypeEnum(element) ?: return null
|
||||
return usageType.toUsageType()
|
||||
}
|
||||
|
||||
private fun getCommonUsageType(refExpr: KtReferenceExpression): UsageTypeEnum? = when {
|
||||
refExpr.getNonStrictParentOfType<KtImportDirective>() != null -> CLASS_IMPORT
|
||||
refExpr.getParentOfTypeAndBranch<KtCallableReferenceExpression> { callableReference } != null -> CALLABLE_REFERENCE
|
||||
else -> null
|
||||
}
|
||||
|
||||
protected fun getClassUsageType(refExpr: KtReferenceExpression): UsageTypeEnum? {
|
||||
if (refExpr.getNonStrictParentOfType<KtTypeProjection>() != null) return TYPE_PARAMETER
|
||||
|
||||
val property = refExpr.getNonStrictParentOfType<KtProperty>()
|
||||
if (property != null) {
|
||||
when {
|
||||
property.typeReference.isAncestor(refExpr) ->
|
||||
return if (property.isLocal) CLASS_LOCAL_VAR_DECLARATION else NON_LOCAL_PROPERTY_TYPE
|
||||
|
||||
property.receiverTypeReference.isAncestor(refExpr) ->
|
||||
return EXTENSION_RECEIVER_TYPE
|
||||
}
|
||||
}
|
||||
|
||||
val function = refExpr.getNonStrictParentOfType<KtFunction>()
|
||||
if (function != null) {
|
||||
when {
|
||||
function.typeReference.isAncestor(refExpr) ->
|
||||
return FUNCTION_RETURN_TYPE
|
||||
function.receiverTypeReference.isAncestor(refExpr) ->
|
||||
return EXTENSION_RECEIVER_TYPE
|
||||
}
|
||||
}
|
||||
|
||||
return when {
|
||||
refExpr.getParentOfTypeAndBranch<KtTypeParameter> { extendsBound } != null || refExpr.getParentOfTypeAndBranch<KtTypeConstraint> { boundTypeReference } != null -> TYPE_CONSTRAINT
|
||||
|
||||
refExpr is KtSuperTypeListEntry || refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry> { typeReference } != null -> SUPER_TYPE
|
||||
|
||||
refExpr.getParentOfTypeAndBranch<KtParameter> { typeReference } != null -> VALUE_PARAMETER_TYPE
|
||||
|
||||
refExpr.getParentOfTypeAndBranch<KtIsExpression> { typeReference } != null || refExpr.getParentOfTypeAndBranch<KtWhenConditionIsPattern> { typeReference } != null -> IS
|
||||
|
||||
with(refExpr.getParentOfTypeAndBranch<KtBinaryExpressionWithTypeRHS> { right }) {
|
||||
val opType = this?.operationReference?.getReferencedNameElementType()
|
||||
opType == org.jetbrains.kotlin.lexer.KtTokens.AS_KEYWORD || opType == org.jetbrains.kotlin.lexer.KtTokens.AS_SAFE
|
||||
} -> CLASS_CAST_TO
|
||||
|
||||
with(refExpr.getNonStrictParentOfType<KtDotQualifiedExpression>()) {
|
||||
when {
|
||||
this == null -> {
|
||||
false
|
||||
}
|
||||
receiverExpression == refExpr -> {
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
selectorExpression == refExpr
|
||||
&& getParentOfTypeAndBranch<KtDotQualifiedExpression>(strict = true) { receiverExpression } != null
|
||||
}
|
||||
}
|
||||
} -> CLASS_OBJECT_ACCESS
|
||||
|
||||
refExpr.getParentOfTypeAndBranch<KtSuperExpression> { superTypeQualifier } != null -> SUPER_TYPE_QUALIFIER
|
||||
|
||||
refExpr.getParentOfTypeAndBranch<KtTypeAlias> { getTypeReference() } != null -> TYPE_ALIAS
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
protected fun getVariableUsageType(refExpr: KtReferenceExpression): UsageTypeEnum? {
|
||||
if (refExpr.getParentOfTypeAndBranch<KtDelegatedSuperTypeEntry> { delegateExpression } != null) return DELEGATE
|
||||
|
||||
if (refExpr.parent is KtValueArgumentName) return NAMED_ARGUMENT
|
||||
|
||||
val dotQualifiedExpression = refExpr.getNonStrictParentOfType<KtDotQualifiedExpression>()
|
||||
|
||||
if (dotQualifiedExpression != null) {
|
||||
val parent = dotQualifiedExpression.parent
|
||||
when {
|
||||
dotQualifiedExpression.receiverExpression.isAncestor(refExpr) ->
|
||||
return RECEIVER
|
||||
|
||||
parent is KtDotQualifiedExpression && parent.receiverExpression.isAncestor(refExpr) ->
|
||||
return RECEIVER
|
||||
}
|
||||
}
|
||||
|
||||
return when (refExpr.readWriteAccess(useResolveForReadWrite = true)) {
|
||||
ReferenceAccess.READ -> READ
|
||||
ReferenceAccess.WRITE, ReferenceAccess.READ_WRITE -> WRITE
|
||||
}
|
||||
}
|
||||
|
||||
protected fun getPackageUsageType(refExpr: KtReferenceExpression): UsageTypeEnum? = when {
|
||||
refExpr.getNonStrictParentOfType<KtPackageDirective>() != null -> PACKAGE_DIRECTIVE
|
||||
refExpr.getNonStrictParentOfType<KtQualifiedExpression>() != null -> PACKAGE_MEMBER_ACCESS
|
||||
else -> getClassUsageType(refExpr)
|
||||
}
|
||||
}
|
||||
|
||||
enum class UsageTypeEnum {
|
||||
TYPE_CONSTRAINT,
|
||||
VALUE_PARAMETER_TYPE,
|
||||
NON_LOCAL_PROPERTY_TYPE,
|
||||
FUNCTION_RETURN_TYPE,
|
||||
SUPER_TYPE,
|
||||
IS,
|
||||
CLASS_OBJECT_ACCESS,
|
||||
COMPANION_OBJECT_ACCESS,
|
||||
EXTENSION_RECEIVER_TYPE,
|
||||
SUPER_TYPE_QUALIFIER,
|
||||
TYPE_ALIAS,
|
||||
|
||||
FUNCTION_CALL,
|
||||
IMPLICIT_GET,
|
||||
IMPLICIT_SET,
|
||||
IMPLICIT_INVOKE,
|
||||
IMPLICIT_ITERATION,
|
||||
PROPERTY_DELEGATION,
|
||||
|
||||
RECEIVER,
|
||||
DELEGATE,
|
||||
|
||||
PACKAGE_DIRECTIVE,
|
||||
PACKAGE_MEMBER_ACCESS,
|
||||
|
||||
CALLABLE_REFERENCE,
|
||||
|
||||
READ,
|
||||
WRITE,
|
||||
CLASS_IMPORT,
|
||||
CLASS_LOCAL_VAR_DECLARATION,
|
||||
TYPE_PARAMETER,
|
||||
CLASS_CAST_TO,
|
||||
ANNOTATION,
|
||||
CLASS_NEW_OPERATOR,
|
||||
NAMED_ARGUMENT,
|
||||
|
||||
USAGE_IN_STRING_LITERAL
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.findUsages
|
||||
|
||||
import com.intellij.usages.impl.rules.UsageType
|
||||
import org.jetbrains.kotlin.idea.KotlinBundleIndependent
|
||||
|
||||
object KotlinUsageTypes {
|
||||
|
||||
internal fun UsageTypeEnum.toUsageType(): UsageType = when (this) {
|
||||
UsageTypeEnum.TYPE_CONSTRAINT -> TYPE_CONSTRAINT
|
||||
UsageTypeEnum.VALUE_PARAMETER_TYPE -> VALUE_PARAMETER_TYPE
|
||||
UsageTypeEnum.NON_LOCAL_PROPERTY_TYPE -> NON_LOCAL_PROPERTY_TYPE
|
||||
UsageTypeEnum.FUNCTION_RETURN_TYPE -> FUNCTION_RETURN_TYPE
|
||||
UsageTypeEnum.SUPER_TYPE -> SUPER_TYPE
|
||||
UsageTypeEnum.IS -> IS
|
||||
UsageTypeEnum.CLASS_OBJECT_ACCESS -> CLASS_OBJECT_ACCESS
|
||||
UsageTypeEnum.COMPANION_OBJECT_ACCESS -> COMPANION_OBJECT_ACCESS
|
||||
UsageTypeEnum.EXTENSION_RECEIVER_TYPE -> EXTENSION_RECEIVER_TYPE
|
||||
UsageTypeEnum.SUPER_TYPE_QUALIFIER -> SUPER_TYPE_QUALIFIER
|
||||
UsageTypeEnum.TYPE_ALIAS -> TYPE_ALIAS
|
||||
|
||||
UsageTypeEnum.FUNCTION_CALL -> FUNCTION_CALL
|
||||
UsageTypeEnum.IMPLICIT_GET -> IMPLICIT_GET
|
||||
UsageTypeEnum.IMPLICIT_SET -> IMPLICIT_SET
|
||||
UsageTypeEnum.IMPLICIT_INVOKE -> IMPLICIT_INVOKE
|
||||
UsageTypeEnum.IMPLICIT_ITERATION -> IMPLICIT_ITERATION
|
||||
UsageTypeEnum.PROPERTY_DELEGATION -> PROPERTY_DELEGATION
|
||||
|
||||
UsageTypeEnum.RECEIVER -> RECEIVER
|
||||
UsageTypeEnum.DELEGATE -> DELEGATE
|
||||
|
||||
UsageTypeEnum.PACKAGE_DIRECTIVE -> PACKAGE_DIRECTIVE
|
||||
UsageTypeEnum.PACKAGE_MEMBER_ACCESS -> PACKAGE_MEMBER_ACCESS
|
||||
|
||||
UsageTypeEnum.CALLABLE_REFERENCE -> CALLABLE_REFERENCE
|
||||
|
||||
UsageTypeEnum.READ -> UsageType.READ
|
||||
UsageTypeEnum.WRITE -> UsageType.WRITE
|
||||
UsageTypeEnum.CLASS_IMPORT -> UsageType.CLASS_IMPORT
|
||||
UsageTypeEnum.CLASS_LOCAL_VAR_DECLARATION -> UsageType.CLASS_LOCAL_VAR_DECLARATION
|
||||
UsageTypeEnum.TYPE_PARAMETER -> UsageType.TYPE_PARAMETER
|
||||
UsageTypeEnum.CLASS_CAST_TO -> UsageType.CLASS_CAST_TO
|
||||
UsageTypeEnum.ANNOTATION -> UsageType.ANNOTATION
|
||||
UsageTypeEnum.CLASS_NEW_OPERATOR -> UsageType.CLASS_NEW_OPERATOR
|
||||
UsageTypeEnum.NAMED_ARGUMENT -> NAMED_ARGUMENT
|
||||
|
||||
UsageTypeEnum.USAGE_IN_STRING_LITERAL -> UsageType.LITERAL_USAGE
|
||||
}
|
||||
|
||||
// types
|
||||
val TYPE_CONSTRAINT = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.type.constraint"))
|
||||
val VALUE_PARAMETER_TYPE = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.value.parameter.type"))
|
||||
val NON_LOCAL_PROPERTY_TYPE = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.nonLocal.property.type"))
|
||||
val FUNCTION_RETURN_TYPE = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.function.return.type"))
|
||||
val SUPER_TYPE = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.superType"))
|
||||
val IS = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.is"))
|
||||
val CLASS_OBJECT_ACCESS = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.class.object"))
|
||||
val COMPANION_OBJECT_ACCESS = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.companion.object"))
|
||||
val EXTENSION_RECEIVER_TYPE = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.extension.receiver.type"))
|
||||
val SUPER_TYPE_QUALIFIER = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.super.type.qualifier"))
|
||||
val TYPE_ALIAS = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.type.alias"))
|
||||
|
||||
// functions
|
||||
val FUNCTION_CALL = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.function.call"))
|
||||
val IMPLICIT_GET = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.implicit.get"))
|
||||
val IMPLICIT_SET = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.implicit.set"))
|
||||
val IMPLICIT_INVOKE = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.implicit.invoke"))
|
||||
val IMPLICIT_ITERATION = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.implicit.iteration"))
|
||||
val PROPERTY_DELEGATION = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.property.delegation"))
|
||||
|
||||
// values
|
||||
val RECEIVER = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.receiver"))
|
||||
val DELEGATE = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.delegate"))
|
||||
|
||||
// packages
|
||||
val PACKAGE_DIRECTIVE = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.packageDirective"))
|
||||
val PACKAGE_MEMBER_ACCESS = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.packageMemberAccess"))
|
||||
|
||||
// common usage types
|
||||
val CALLABLE_REFERENCE = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.callable.reference"))
|
||||
val NAMED_ARGUMENT = UsageType(KotlinBundleIndependent.lazyMessage("find.usages.type.named.argument"))
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.findUsages
|
||||
|
||||
import com.intellij.usages.impl.rules.UsageType
|
||||
import org.jetbrains.kotlin.idea.KotlinBundleIndependent
|
||||
|
||||
object KotlinUsageTypes {
|
||||
|
||||
internal fun UsageTypeEnum.toUsageType(): UsageType = when (this) {
|
||||
UsageTypeEnum.TYPE_CONSTRAINT -> TYPE_CONSTRAINT
|
||||
UsageTypeEnum.VALUE_PARAMETER_TYPE -> VALUE_PARAMETER_TYPE
|
||||
UsageTypeEnum.NON_LOCAL_PROPERTY_TYPE -> NON_LOCAL_PROPERTY_TYPE
|
||||
UsageTypeEnum.FUNCTION_RETURN_TYPE -> FUNCTION_RETURN_TYPE
|
||||
UsageTypeEnum.SUPER_TYPE -> SUPER_TYPE
|
||||
UsageTypeEnum.IS -> IS
|
||||
UsageTypeEnum.CLASS_OBJECT_ACCESS -> CLASS_OBJECT_ACCESS
|
||||
UsageTypeEnum.COMPANION_OBJECT_ACCESS -> COMPANION_OBJECT_ACCESS
|
||||
UsageTypeEnum.EXTENSION_RECEIVER_TYPE -> EXTENSION_RECEIVER_TYPE
|
||||
UsageTypeEnum.SUPER_TYPE_QUALIFIER -> SUPER_TYPE_QUALIFIER
|
||||
UsageTypeEnum.TYPE_ALIAS -> TYPE_ALIAS
|
||||
|
||||
UsageTypeEnum.FUNCTION_CALL -> FUNCTION_CALL
|
||||
UsageTypeEnum.IMPLICIT_GET -> IMPLICIT_GET
|
||||
UsageTypeEnum.IMPLICIT_SET -> IMPLICIT_SET
|
||||
UsageTypeEnum.IMPLICIT_INVOKE -> IMPLICIT_INVOKE
|
||||
UsageTypeEnum.IMPLICIT_ITERATION -> IMPLICIT_ITERATION
|
||||
UsageTypeEnum.PROPERTY_DELEGATION -> PROPERTY_DELEGATION
|
||||
|
||||
UsageTypeEnum.RECEIVER -> RECEIVER
|
||||
UsageTypeEnum.DELEGATE -> DELEGATE
|
||||
|
||||
UsageTypeEnum.PACKAGE_DIRECTIVE -> PACKAGE_DIRECTIVE
|
||||
UsageTypeEnum.PACKAGE_MEMBER_ACCESS -> PACKAGE_MEMBER_ACCESS
|
||||
|
||||
UsageTypeEnum.CALLABLE_REFERENCE -> CALLABLE_REFERENCE
|
||||
|
||||
UsageTypeEnum.READ -> UsageType.READ
|
||||
UsageTypeEnum.WRITE -> UsageType.WRITE
|
||||
UsageTypeEnum.CLASS_IMPORT -> UsageType.CLASS_IMPORT
|
||||
UsageTypeEnum.CLASS_LOCAL_VAR_DECLARATION -> UsageType.CLASS_LOCAL_VAR_DECLARATION
|
||||
UsageTypeEnum.TYPE_PARAMETER -> UsageType.TYPE_PARAMETER
|
||||
UsageTypeEnum.CLASS_CAST_TO -> UsageType.CLASS_CAST_TO
|
||||
UsageTypeEnum.ANNOTATION -> UsageType.ANNOTATION
|
||||
UsageTypeEnum.CLASS_NEW_OPERATOR -> UsageType.CLASS_NEW_OPERATOR
|
||||
UsageTypeEnum.NAMED_ARGUMENT -> NAMED_ARGUMENT
|
||||
|
||||
UsageTypeEnum.USAGE_IN_STRING_LITERAL -> UsageType.LITERAL_USAGE
|
||||
}
|
||||
|
||||
// types
|
||||
val TYPE_CONSTRAINT = UsageType(KotlinBundleIndependent.message("find.usages.type.type.constraint"))
|
||||
val VALUE_PARAMETER_TYPE = UsageType(KotlinBundleIndependent.message("find.usages.type.value.parameter.type"))
|
||||
val NON_LOCAL_PROPERTY_TYPE = UsageType(KotlinBundleIndependent.message("find.usages.type.nonLocal.property.type"))
|
||||
val FUNCTION_RETURN_TYPE = UsageType(KotlinBundleIndependent.message("find.usages.type.function.return.type"))
|
||||
val SUPER_TYPE = UsageType(KotlinBundleIndependent.message("find.usages.type.superType"))
|
||||
val IS = UsageType(KotlinBundleIndependent.message("find.usages.type.is"))
|
||||
val CLASS_OBJECT_ACCESS = UsageType(KotlinBundleIndependent.message("find.usages.type.class.object"))
|
||||
val COMPANION_OBJECT_ACCESS = UsageType(KotlinBundleIndependent.message("find.usages.type.companion.object"))
|
||||
val EXTENSION_RECEIVER_TYPE = UsageType(KotlinBundleIndependent.message("find.usages.type.extension.receiver.type"))
|
||||
val SUPER_TYPE_QUALIFIER = UsageType(KotlinBundleIndependent.message("find.usages.type.super.type.qualifier"))
|
||||
val TYPE_ALIAS = UsageType(KotlinBundleIndependent.message("find.usages.type.type.alias"))
|
||||
|
||||
// functions
|
||||
val FUNCTION_CALL = UsageType(KotlinBundleIndependent.message("find.usages.type.function.call"))
|
||||
val IMPLICIT_GET = UsageType(KotlinBundleIndependent.message("find.usages.type.implicit.get"))
|
||||
val IMPLICIT_SET = UsageType(KotlinBundleIndependent.message("find.usages.type.implicit.set"))
|
||||
val IMPLICIT_INVOKE = UsageType(KotlinBundleIndependent.message("find.usages.type.implicit.invoke"))
|
||||
val IMPLICIT_ITERATION = UsageType(KotlinBundleIndependent.message("find.usages.type.implicit.iteration"))
|
||||
val PROPERTY_DELEGATION = UsageType(KotlinBundleIndependent.message("find.usages.type.property.delegation"))
|
||||
|
||||
// values
|
||||
val RECEIVER = UsageType(KotlinBundleIndependent.message("find.usages.type.receiver"))
|
||||
val DELEGATE = UsageType(KotlinBundleIndependent.message("find.usages.type.delegate"))
|
||||
|
||||
// packages
|
||||
val PACKAGE_DIRECTIVE = UsageType(KotlinBundleIndependent.message("find.usages.type.packageDirective"))
|
||||
val PACKAGE_MEMBER_ACCESS = UsageType(KotlinBundleIndependent.message("find.usages.type.packageMemberAccess"))
|
||||
|
||||
// common usage types
|
||||
val CALLABLE_REFERENCE = UsageType(KotlinBundleIndependent.message("find.usages.type.callable.reference"))
|
||||
val NAMED_ARGUMENT = UsageType(KotlinBundleIndependent.message("find.usages.type.named.argument"))
|
||||
}
|
||||
@@ -444,29 +444,6 @@ filters.text.inline.function.body=inline function body
|
||||
filters.text.inline.function.call.site=inline function call site
|
||||
filters.title.navigate.to=Navigate to
|
||||
|
||||
find.usages.type.named.argument=Named argument
|
||||
find.usages.type.type.alias=Type alias
|
||||
find.usages.type.callable.reference=Callable reference
|
||||
find.usages.type.type.constraint=Type constraint
|
||||
find.usages.type.value.parameter.type=Parameter type
|
||||
find.usages.type.nonLocal.property.type=Class/object property type
|
||||
find.usages.type.function.return.type=Function return types
|
||||
find.usages.type.superType=Supertype
|
||||
find.usages.type.is=Target type of 'is' operation
|
||||
find.usages.type.class.object=Nested class/object
|
||||
find.usages.type.companion.object=Companion object
|
||||
find.usages.type.function.call=Function call
|
||||
find.usages.type.implicit.get=Implicit 'get'
|
||||
find.usages.type.implicit.set=Implicit 'set'
|
||||
find.usages.type.implicit.invoke=Implicit 'invoke'
|
||||
find.usages.type.implicit.iteration=Implicit iteration
|
||||
find.usages.type.property.delegation=Property delegation
|
||||
find.usages.type.extension.receiver.type=Extension receiver type
|
||||
find.usages.type.super.type.qualifier=Super type qualifier
|
||||
find.usages.type.receiver=Receiver
|
||||
find.usages.type.delegate=Delegate
|
||||
find.usages.type.packageDirective=Package directive
|
||||
find.usages.type.packageMemberAccess=Package member access
|
||||
find.usages.progress.text.declaration.superMethods=Resolving super methods...
|
||||
|
||||
formatter.button.text.use.import.with.when.at.least=Use import with '*' when at least
|
||||
|
||||
@@ -209,6 +209,7 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu
|
||||
order="first"/>
|
||||
|
||||
<findUsagesHandlerFactory implementation="org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory"/>
|
||||
<usageTypeProvider implementation="org.jetbrains.kotlin.idea.findUsages.KotlinUsageTypeProviderFirImpl"/>
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupport"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesSupportFirImpl"/>
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport"
|
||||
|
||||
@@ -528,7 +528,7 @@
|
||||
<highlightUsagesHandlerFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightExitPointsHandlerFactory"/>
|
||||
<highlightUsagesHandlerFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightImplicitItHandlerFactory"/>
|
||||
<findUsagesHandlerFactory implementation="org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory"/>
|
||||
<usageTypeProvider implementation="org.jetbrains.kotlin.idea.findUsages.KotlinUsageTypeProvider"/>
|
||||
<usageTypeProvider implementation="org.jetbrains.kotlin.idea.findUsages.KotlinUsageTypeProviderImpl"/>
|
||||
|
||||
<refactoring.safeDeleteProcessor
|
||||
id="kotlinProcessor"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.findUsages
|
||||
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.findUsages
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.usages.UsageTarget
|
||||
import com.intellij.usages.impl.rules.UsageType
|
||||
import com.intellij.usages.impl.rules.UsageTypeProviderEx
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum.*
|
||||
|
||||
object KotlinUsageTypeProvider : UsageTypeProviderEx {
|
||||
override fun getUsageType(element: PsiElement?): UsageType? = getUsageType(element, UsageTarget.EMPTY_ARRAY)
|
||||
|
||||
override fun getUsageType(element: PsiElement?, targets: Array<out UsageTarget>): UsageType? {
|
||||
val usageType = UsageTypeUtils.getUsageType(element) ?: return null
|
||||
return convertEnumToUsageType(usageType)
|
||||
}
|
||||
|
||||
private fun convertEnumToUsageType(usageType: UsageTypeEnum): UsageType = when (usageType) {
|
||||
TYPE_CONSTRAINT -> KotlinUsageTypes.TYPE_CONSTRAINT
|
||||
VALUE_PARAMETER_TYPE -> KotlinUsageTypes.VALUE_PARAMETER_TYPE
|
||||
NON_LOCAL_PROPERTY_TYPE -> KotlinUsageTypes.NON_LOCAL_PROPERTY_TYPE
|
||||
FUNCTION_RETURN_TYPE -> KotlinUsageTypes.FUNCTION_RETURN_TYPE
|
||||
SUPER_TYPE -> KotlinUsageTypes.SUPER_TYPE
|
||||
IS -> KotlinUsageTypes.IS
|
||||
CLASS_OBJECT_ACCESS -> KotlinUsageTypes.CLASS_OBJECT_ACCESS
|
||||
COMPANION_OBJECT_ACCESS -> KotlinUsageTypes.COMPANION_OBJECT_ACCESS
|
||||
EXTENSION_RECEIVER_TYPE -> KotlinUsageTypes.EXTENSION_RECEIVER_TYPE
|
||||
SUPER_TYPE_QUALIFIER -> KotlinUsageTypes.SUPER_TYPE_QUALIFIER
|
||||
TYPE_ALIAS -> KotlinUsageTypes.TYPE_ALIAS
|
||||
|
||||
FUNCTION_CALL -> KotlinUsageTypes.FUNCTION_CALL
|
||||
IMPLICIT_GET -> KotlinUsageTypes.IMPLICIT_GET
|
||||
IMPLICIT_SET -> KotlinUsageTypes.IMPLICIT_SET
|
||||
IMPLICIT_INVOKE -> KotlinUsageTypes.IMPLICIT_INVOKE
|
||||
IMPLICIT_ITERATION -> KotlinUsageTypes.IMPLICIT_ITERATION
|
||||
PROPERTY_DELEGATION -> KotlinUsageTypes.PROPERTY_DELEGATION
|
||||
|
||||
RECEIVER -> KotlinUsageTypes.RECEIVER
|
||||
DELEGATE -> KotlinUsageTypes.DELEGATE
|
||||
|
||||
PACKAGE_DIRECTIVE -> KotlinUsageTypes.PACKAGE_DIRECTIVE
|
||||
PACKAGE_MEMBER_ACCESS -> KotlinUsageTypes.PACKAGE_MEMBER_ACCESS
|
||||
|
||||
CALLABLE_REFERENCE -> KotlinUsageTypes.CALLABLE_REFERENCE
|
||||
|
||||
READ -> UsageType.READ
|
||||
WRITE -> UsageType.WRITE
|
||||
CLASS_IMPORT -> UsageType.CLASS_IMPORT
|
||||
CLASS_LOCAL_VAR_DECLARATION -> UsageType.CLASS_LOCAL_VAR_DECLARATION
|
||||
TYPE_PARAMETER -> UsageType.TYPE_PARAMETER
|
||||
CLASS_CAST_TO -> UsageType.CLASS_CAST_TO
|
||||
ANNOTATION -> UsageType.ANNOTATION
|
||||
CLASS_NEW_OPERATOR -> UsageType.CLASS_NEW_OPERATOR
|
||||
NAMED_ARGUMENT -> KotlinUsageTypes.NAMED_ARGUMENT
|
||||
|
||||
USAGE_IN_STRING_LITERAL -> UsageType.LITERAL_USAGE
|
||||
}
|
||||
}
|
||||
|
||||
object KotlinUsageTypes {
|
||||
// types
|
||||
val TYPE_CONSTRAINT = UsageType(KotlinBundle.lazyMessage("find.usages.type.type.constraint"))
|
||||
val VALUE_PARAMETER_TYPE = UsageType(KotlinBundle.lazyMessage("find.usages.type.value.parameter.type"))
|
||||
val NON_LOCAL_PROPERTY_TYPE = UsageType(KotlinBundle.lazyMessage("find.usages.type.nonLocal.property.type"))
|
||||
val FUNCTION_RETURN_TYPE = UsageType(KotlinBundle.lazyMessage("find.usages.type.function.return.type"))
|
||||
val SUPER_TYPE = UsageType(KotlinBundle.lazyMessage("find.usages.type.superType"))
|
||||
val IS = UsageType(KotlinBundle.lazyMessage("find.usages.type.is"))
|
||||
val CLASS_OBJECT_ACCESS = UsageType(KotlinBundle.lazyMessage("find.usages.type.class.object"))
|
||||
val COMPANION_OBJECT_ACCESS = UsageType(KotlinBundle.lazyMessage("find.usages.type.companion.object"))
|
||||
val EXTENSION_RECEIVER_TYPE = UsageType(KotlinBundle.lazyMessage("find.usages.type.extension.receiver.type"))
|
||||
val SUPER_TYPE_QUALIFIER = UsageType(KotlinBundle.lazyMessage("find.usages.type.super.type.qualifier"))
|
||||
val TYPE_ALIAS = UsageType(KotlinBundle.lazyMessage("find.usages.type.type.alias"))
|
||||
|
||||
// functions
|
||||
val FUNCTION_CALL = UsageType(KotlinBundle.lazyMessage("find.usages.type.function.call"))
|
||||
val IMPLICIT_GET = UsageType(KotlinBundle.lazyMessage("find.usages.type.implicit.get"))
|
||||
val IMPLICIT_SET = UsageType(KotlinBundle.lazyMessage("find.usages.type.implicit.set"))
|
||||
val IMPLICIT_INVOKE = UsageType(KotlinBundle.lazyMessage("find.usages.type.implicit.invoke"))
|
||||
val IMPLICIT_ITERATION = UsageType(KotlinBundle.lazyMessage("find.usages.type.implicit.iteration"))
|
||||
val PROPERTY_DELEGATION = UsageType(KotlinBundle.lazyMessage("find.usages.type.property.delegation"))
|
||||
|
||||
// values
|
||||
val RECEIVER = UsageType(KotlinBundle.lazyMessage("find.usages.type.receiver"))
|
||||
val DELEGATE = UsageType(KotlinBundle.lazyMessage("find.usages.type.delegate"))
|
||||
|
||||
// packages
|
||||
val PACKAGE_DIRECTIVE = UsageType(KotlinBundle.lazyMessage("find.usages.type.packageDirective"))
|
||||
val PACKAGE_MEMBER_ACCESS = UsageType(KotlinBundle.lazyMessage("find.usages.type.packageMemberAccess"))
|
||||
|
||||
// common usage types
|
||||
val CALLABLE_REFERENCE = UsageType(KotlinBundle.lazyMessage("find.usages.type.callable.reference"))
|
||||
val NAMED_ARGUMENT = UsageType(KotlinBundle.lazyMessage("find.usages.type.named.argument"))
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.findUsages
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.usages.UsageTarget
|
||||
import com.intellij.usages.impl.rules.UsageType
|
||||
import com.intellij.usages.impl.rules.UsageTypeProviderEx
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum.*
|
||||
|
||||
object KotlinUsageTypeProvider : UsageTypeProviderEx {
|
||||
override fun getUsageType(element: PsiElement?): UsageType? = getUsageType(element, UsageTarget.EMPTY_ARRAY)
|
||||
|
||||
override fun getUsageType(element: PsiElement?, targets: Array<out UsageTarget>): UsageType? {
|
||||
val usageType = UsageTypeUtils.getUsageType(element) ?: return null
|
||||
return convertEnumToUsageType(usageType)
|
||||
}
|
||||
|
||||
private fun convertEnumToUsageType(usageType: UsageTypeEnum): UsageType = when (usageType) {
|
||||
TYPE_CONSTRAINT -> KotlinUsageTypes.TYPE_CONSTRAINT
|
||||
VALUE_PARAMETER_TYPE -> KotlinUsageTypes.VALUE_PARAMETER_TYPE
|
||||
NON_LOCAL_PROPERTY_TYPE -> KotlinUsageTypes.NON_LOCAL_PROPERTY_TYPE
|
||||
FUNCTION_RETURN_TYPE -> KotlinUsageTypes.FUNCTION_RETURN_TYPE
|
||||
SUPER_TYPE -> KotlinUsageTypes.SUPER_TYPE
|
||||
IS -> KotlinUsageTypes.IS
|
||||
CLASS_OBJECT_ACCESS -> KotlinUsageTypes.CLASS_OBJECT_ACCESS
|
||||
COMPANION_OBJECT_ACCESS -> KotlinUsageTypes.COMPANION_OBJECT_ACCESS
|
||||
EXTENSION_RECEIVER_TYPE -> KotlinUsageTypes.EXTENSION_RECEIVER_TYPE
|
||||
SUPER_TYPE_QUALIFIER -> KotlinUsageTypes.SUPER_TYPE_QUALIFIER
|
||||
TYPE_ALIAS -> KotlinUsageTypes.TYPE_ALIAS
|
||||
|
||||
FUNCTION_CALL -> KotlinUsageTypes.FUNCTION_CALL
|
||||
IMPLICIT_GET -> KotlinUsageTypes.IMPLICIT_GET
|
||||
IMPLICIT_SET -> KotlinUsageTypes.IMPLICIT_SET
|
||||
IMPLICIT_INVOKE -> KotlinUsageTypes.IMPLICIT_INVOKE
|
||||
IMPLICIT_ITERATION -> KotlinUsageTypes.IMPLICIT_ITERATION
|
||||
PROPERTY_DELEGATION -> KotlinUsageTypes.PROPERTY_DELEGATION
|
||||
|
||||
RECEIVER -> KotlinUsageTypes.RECEIVER
|
||||
DELEGATE -> KotlinUsageTypes.DELEGATE
|
||||
|
||||
PACKAGE_DIRECTIVE -> KotlinUsageTypes.PACKAGE_DIRECTIVE
|
||||
PACKAGE_MEMBER_ACCESS -> KotlinUsageTypes.PACKAGE_MEMBER_ACCESS
|
||||
|
||||
CALLABLE_REFERENCE -> KotlinUsageTypes.CALLABLE_REFERENCE
|
||||
|
||||
READ -> UsageType.READ
|
||||
WRITE -> UsageType.WRITE
|
||||
CLASS_IMPORT -> UsageType.CLASS_IMPORT
|
||||
CLASS_LOCAL_VAR_DECLARATION -> UsageType.CLASS_LOCAL_VAR_DECLARATION
|
||||
TYPE_PARAMETER -> UsageType.TYPE_PARAMETER
|
||||
CLASS_CAST_TO -> UsageType.CLASS_CAST_TO
|
||||
ANNOTATION -> UsageType.ANNOTATION
|
||||
CLASS_NEW_OPERATOR -> UsageType.CLASS_NEW_OPERATOR
|
||||
NAMED_ARGUMENT -> KotlinUsageTypes.NAMED_ARGUMENT
|
||||
|
||||
USAGE_IN_STRING_LITERAL -> UsageType.LITERAL_USAGE
|
||||
}
|
||||
}
|
||||
|
||||
object KotlinUsageTypes {
|
||||
// types
|
||||
val TYPE_CONSTRAINT = UsageType(KotlinBundle.message("find.usages.type.type.constraint"))
|
||||
val VALUE_PARAMETER_TYPE = UsageType(KotlinBundle.message("find.usages.type.value.parameter.type"))
|
||||
val NON_LOCAL_PROPERTY_TYPE = UsageType(KotlinBundle.message("find.usages.type.nonLocal.property.type"))
|
||||
val FUNCTION_RETURN_TYPE = UsageType(KotlinBundle.message("find.usages.type.function.return.type"))
|
||||
val SUPER_TYPE = UsageType(KotlinBundle.message("find.usages.type.superType"))
|
||||
val IS = UsageType(KotlinBundle.message("find.usages.type.is"))
|
||||
val CLASS_OBJECT_ACCESS = UsageType(KotlinBundle.message("find.usages.type.class.object"))
|
||||
val COMPANION_OBJECT_ACCESS = UsageType(KotlinBundle.message("find.usages.type.companion.object"))
|
||||
val EXTENSION_RECEIVER_TYPE = UsageType(KotlinBundle.message("find.usages.type.extension.receiver.type"))
|
||||
val SUPER_TYPE_QUALIFIER = UsageType(KotlinBundle.message("find.usages.type.super.type.qualifier"))
|
||||
val TYPE_ALIAS = UsageType(KotlinBundle.message("find.usages.type.type.alias"))
|
||||
|
||||
// functions
|
||||
val FUNCTION_CALL = UsageType(KotlinBundle.message("find.usages.type.function.call"))
|
||||
val IMPLICIT_GET = UsageType(KotlinBundle.message("find.usages.type.implicit.get"))
|
||||
val IMPLICIT_SET = UsageType(KotlinBundle.message("find.usages.type.implicit.set"))
|
||||
val IMPLICIT_INVOKE = UsageType(KotlinBundle.message("find.usages.type.implicit.invoke"))
|
||||
val IMPLICIT_ITERATION = UsageType(KotlinBundle.message("find.usages.type.implicit.iteration"))
|
||||
val PROPERTY_DELEGATION = UsageType(KotlinBundle.message("find.usages.type.property.delegation"))
|
||||
|
||||
// values
|
||||
val RECEIVER = UsageType(KotlinBundle.message("find.usages.type.receiver"))
|
||||
val DELEGATE = UsageType(KotlinBundle.message("find.usages.type.delegate"))
|
||||
|
||||
// packages
|
||||
val PACKAGE_DIRECTIVE = UsageType(KotlinBundle.message("find.usages.type.packageDirective"))
|
||||
val PACKAGE_MEMBER_ACCESS = UsageType(KotlinBundle.message("find.usages.type.packageMemberAccess"))
|
||||
|
||||
// common usage types
|
||||
val CALLABLE_REFERENCE = UsageType(KotlinBundle.message("find.usages.type.callable.reference"))
|
||||
val NAMED_ARGUMENT = UsageType(KotlinBundle.message("find.usages.type.named.argument"))
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.findUsages
|
||||
|
||||
import com.intellij.psi.PsiPackage
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.references.KtArrayAccessReference
|
||||
import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.idea.findUsages.UsageTypeEnum.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
class KotlinUsageTypeProviderImpl : KotlinUsageTypeProvider() {
|
||||
|
||||
override fun getUsageTypeEnumByReference(refExpr: KtReferenceExpression): UsageTypeEnum? {
|
||||
|
||||
val context = refExpr.analyze(BodyResolveMode.PARTIAL)
|
||||
|
||||
fun getFunctionUsageTypeDescriptor(descriptor: FunctionDescriptor): UsageTypeEnum? {
|
||||
when (refExpr.mainReference) {
|
||||
is KtArrayAccessReference -> {
|
||||
return when {
|
||||
context[BindingContext.INDEXED_LVALUE_GET, refExpr] != null -> IMPLICIT_GET
|
||||
context[BindingContext.INDEXED_LVALUE_SET, refExpr] != null -> IMPLICIT_SET
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
is KtInvokeFunctionReference -> return IMPLICIT_INVOKE
|
||||
}
|
||||
|
||||
return when {
|
||||
refExpr.getParentOfTypeAndBranch<KtSuperTypeListEntry> { typeReference } != null -> SUPER_TYPE
|
||||
|
||||
descriptor is ConstructorDescriptor && refExpr.getParentOfTypeAndBranch<KtAnnotationEntry> { typeReference } != null -> ANNOTATION
|
||||
|
||||
with(refExpr.getParentOfTypeAndBranch<KtCallExpression> { calleeExpression }) {
|
||||
this?.calleeExpression is KtSimpleNameExpression
|
||||
} -> if (descriptor is ConstructorDescriptor) CLASS_NEW_OPERATOR else FUNCTION_CALL
|
||||
|
||||
refExpr.getParentOfTypeAndBranch<KtBinaryExpression> { operationReference } != null || refExpr.getParentOfTypeAndBranch<KtUnaryExpression> { operationReference } != null || refExpr.getParentOfTypeAndBranch<KtWhenConditionInRange> { operationReference } != null -> FUNCTION_CALL
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
return when (val descriptor = context[BindingContext.REFERENCE_TARGET, refExpr]) {
|
||||
is ClassifierDescriptor -> when {
|
||||
// Treat object accesses as variables to simulate the old behaviour (when variables were created for objects)
|
||||
DescriptorUtils.isNonCompanionObject(descriptor) || DescriptorUtils.isEnumEntry(descriptor) -> getVariableUsageType(refExpr)
|
||||
DescriptorUtils.isCompanionObject(descriptor) -> COMPANION_OBJECT_ACCESS
|
||||
else -> getClassUsageType(refExpr)
|
||||
}
|
||||
is PackageViewDescriptor -> {
|
||||
if (refExpr.mainReference.resolve() is PsiPackage) getPackageUsageType(refExpr) else getClassUsageType(refExpr)
|
||||
}
|
||||
is VariableDescriptor -> getVariableUsageType(refExpr)
|
||||
is FunctionDescriptor -> getFunctionUsageTypeDescriptor(descriptor)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user