[FIR IDE] Implement FIR for KotlinUsageTypeProvider

This commit is contained in:
Igor Yakovlev
2020-09-16 20:37:14 +03:00
parent 37ba9eccc4
commit d534d92123
13 changed files with 535 additions and 452 deletions
@@ -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)
//}
@@ -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
}
}
}
}
@@ -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
@@ -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
}
@@ -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"))
}
@@ -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
+1
View File
@@ -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"
+1 -1
View File
@@ -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
}
}
}