From d534d92123c025ab737c35bb34ff5dc2eabdb523 Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Wed, 16 Sep 2020 20:37:14 +0300 Subject: [PATCH] [FIR IDE] Implement FIR for KotlinUsageTypeProvider --- .../kotlin/idea/findUsages/UsageTypeUtils.kt | 216 +----------------- .../KotlinUsageTypeProviderFirImpl.kt | 73 ++++++ .../KotlinBundleIndependent.properties | 24 ++ .../findUsages/KotlinUsageTypeProvider.kt | 181 +++++++++++++++ .../idea/findUsages/KotlinUsageTypes.kt | 86 +++++++ .../idea/findUsages/KotlinUsageTypes.kt.193 | 86 +++++++ .../messages/KotlinBundle.properties | 23 -- idea/resources-fir/META-INF/plugin.xml | 1 + idea/resources/META-INF/plugin-common.xml | 2 +- .../findUsages/KotlinUsageTypeGetterImpl.kt | 8 + .../findUsages/KotlinUsageTypeProvider.kt | 109 --------- .../findUsages/KotlinUsageTypeProvider.kt.193 | 109 --------- .../findUsages/KotlinUsageTypeProviderImpl.kt | 69 ++++++ 13 files changed, 535 insertions(+), 452 deletions(-) create mode 100644 idea/idea-fir/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProviderFirImpl.kt create mode 100644 idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProvider.kt create mode 100644 idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypes.kt create mode 100644 idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypes.kt.193 create mode 100644 idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeGetterImpl.kt delete mode 100644 idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProvider.kt delete mode 100644 idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProvider.kt.193 create mode 100644 idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProviderImpl.kt diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/findUsages/UsageTypeUtils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/findUsages/UsageTypeUtils.kt index c47830f5d00..c04d238c318 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/findUsages/UsageTypeUtils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/findUsages/UsageTypeUtils.kt @@ -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() ?: return null - - val context = refExpr.analyze(BodyResolveMode.PARTIAL) - - fun getCommonUsageType(): UsageTypeEnum? = when { - refExpr.getNonStrictParentOfType() != null -> CLASS_IMPORT - refExpr.getParentOfTypeAndBranch() { callableReference } != null -> CALLABLE_REFERENCE - else -> null - } - - fun getClassUsageType(): UsageTypeEnum? { - if (refExpr.getNonStrictParentOfType() != null) return TYPE_PARAMETER - - val property = refExpr.getNonStrictParentOfType() - 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() - if (function != null) { - when { - function.typeReference.isAncestor(refExpr) -> - return FUNCTION_RETURN_TYPE - function.receiverTypeReference.isAncestor(refExpr) -> - return EXTENSION_RECEIVER_TYPE - } - } - - return when { - refExpr.getParentOfTypeAndBranch() { extendsBound } != null || refExpr.getParentOfTypeAndBranch() { boundTypeReference } != null -> TYPE_CONSTRAINT - - refExpr is KtSuperTypeListEntry || refExpr.getParentOfTypeAndBranch() { typeReference } != null -> SUPER_TYPE - - refExpr.getParentOfTypeAndBranch() { typeReference } != null -> VALUE_PARAMETER_TYPE - - refExpr.getParentOfTypeAndBranch() { typeReference } != null || refExpr.getParentOfTypeAndBranch() { typeReference } != null -> IS - - with(refExpr.getParentOfTypeAndBranch() { right }) { - val opType = this?.operationReference?.getReferencedNameElementType() - opType == KtTokens.AS_KEYWORD || opType == KtTokens.AS_SAFE - } -> CLASS_CAST_TO - - with(refExpr.getNonStrictParentOfType()) { - when { - this == null -> { - false - } - receiverExpression == refExpr -> { - true - } - else -> { - selectorExpression == refExpr - && getParentOfTypeAndBranch(strict = true) { receiverExpression } != null - } - } - } -> CLASS_OBJECT_ACCESS - - refExpr.getParentOfTypeAndBranch() { superTypeQualifier } != null -> SUPER_TYPE_QUALIFIER - - refExpr.getParentOfTypeAndBranch { getTypeReference() } != null -> TYPE_ALIAS - - else -> null - } - } - - fun getVariableUsageType(): UsageTypeEnum? { - if (refExpr.getParentOfTypeAndBranch() { delegateExpression } != null) return DELEGATE - - if (refExpr.parent is KtValueArgumentName) return NAMED_ARGUMENT - - val dotQualifiedExpression = refExpr.getNonStrictParentOfType() - - 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() { typeReference } != null -> SUPER_TYPE - - descriptor is ConstructorDescriptor && refExpr.getParentOfTypeAndBranch() { typeReference } != null -> ANNOTATION - - with(refExpr.getParentOfTypeAndBranch() { calleeExpression }) { - this?.calleeExpression is KtSimpleNameExpression - } -> if (descriptor is ConstructorDescriptor) CLASS_NEW_OPERATOR else FUNCTION_CALL - - refExpr.getParentOfTypeAndBranch() { operationReference } != null || refExpr.getParentOfTypeAndBranch() { operationReference } != null || refExpr.getParentOfTypeAndBranch() { operationReference } != null -> FUNCTION_CALL - - else -> null - } - } - - fun getPackageUsageType(): UsageTypeEnum? = when { - refExpr.getNonStrictParentOfType() != null -> PACKAGE_DIRECTIVE - refExpr.getNonStrictParentOfType() != 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().getUsageTypeEnum(element) +//} \ No newline at end of file diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProviderFirImpl.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProviderFirImpl.kt new file mode 100644 index 00000000000..c0093f2d15a --- /dev/null +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProviderFirImpl.kt @@ -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 { typeReference } != null -> SUPER_TYPE + + functionSymbol is KtConstructorSymbol && refExpr.getParentOfTypeAndBranch { typeReference } != null -> ANNOTATION + + with(refExpr.getParentOfTypeAndBranch { calleeExpression }) { + this?.calleeExpression is KtSimpleNameExpression + } -> if (functionSymbol is KtConstructorSymbol) CLASS_NEW_OPERATOR else FUNCTION_CALL //HLAPI resolveCall -> CallInfo -> + + refExpr.getParentOfTypeAndBranch { operationReference } != null || refExpr.getParentOfTypeAndBranch { operationReference } != null || refExpr.getParentOfTypeAndBranch { 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 + } + } + } +} \ No newline at end of file diff --git a/idea/idea-frontend-independent/resources-en/messages/KotlinBundleIndependent.properties b/idea/idea-frontend-independent/resources-en/messages/KotlinBundleIndependent.properties index 90259c526e0..7d2460d460b 100644 --- a/idea/idea-frontend-independent/resources-en/messages/KotlinBundleIndependent.properties +++ b/idea/idea-frontend-independent/resources-en/messages/KotlinBundleIndependent.properties @@ -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 \ No newline at end of file diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProvider.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProvider.kt new file mode 100644 index 00000000000..600a4ebe88a --- /dev/null +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProvider.kt @@ -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() ?: 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): UsageType? { + val usageType = getUsageTypeEnum(element) ?: return null + return usageType.toUsageType() + } + + private fun getCommonUsageType(refExpr: KtReferenceExpression): UsageTypeEnum? = when { + refExpr.getNonStrictParentOfType() != null -> CLASS_IMPORT + refExpr.getParentOfTypeAndBranch { callableReference } != null -> CALLABLE_REFERENCE + else -> null + } + + protected fun getClassUsageType(refExpr: KtReferenceExpression): UsageTypeEnum? { + if (refExpr.getNonStrictParentOfType() != null) return TYPE_PARAMETER + + val property = refExpr.getNonStrictParentOfType() + 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() + if (function != null) { + when { + function.typeReference.isAncestor(refExpr) -> + return FUNCTION_RETURN_TYPE + function.receiverTypeReference.isAncestor(refExpr) -> + return EXTENSION_RECEIVER_TYPE + } + } + + return when { + refExpr.getParentOfTypeAndBranch { extendsBound } != null || refExpr.getParentOfTypeAndBranch { boundTypeReference } != null -> TYPE_CONSTRAINT + + refExpr is KtSuperTypeListEntry || refExpr.getParentOfTypeAndBranch { typeReference } != null -> SUPER_TYPE + + refExpr.getParentOfTypeAndBranch { typeReference } != null -> VALUE_PARAMETER_TYPE + + refExpr.getParentOfTypeAndBranch { typeReference } != null || refExpr.getParentOfTypeAndBranch { typeReference } != null -> IS + + with(refExpr.getParentOfTypeAndBranch { 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()) { + when { + this == null -> { + false + } + receiverExpression == refExpr -> { + true + } + else -> { + selectorExpression == refExpr + && getParentOfTypeAndBranch(strict = true) { receiverExpression } != null + } + } + } -> CLASS_OBJECT_ACCESS + + refExpr.getParentOfTypeAndBranch { superTypeQualifier } != null -> SUPER_TYPE_QUALIFIER + + refExpr.getParentOfTypeAndBranch { getTypeReference() } != null -> TYPE_ALIAS + + else -> null + } + } + + protected fun getVariableUsageType(refExpr: KtReferenceExpression): UsageTypeEnum? { + if (refExpr.getParentOfTypeAndBranch { delegateExpression } != null) return DELEGATE + + if (refExpr.parent is KtValueArgumentName) return NAMED_ARGUMENT + + val dotQualifiedExpression = refExpr.getNonStrictParentOfType() + + 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() != null -> PACKAGE_DIRECTIVE + refExpr.getNonStrictParentOfType() != 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 +} \ No newline at end of file diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypes.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypes.kt new file mode 100644 index 00000000000..b1341955556 --- /dev/null +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypes.kt @@ -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")) +} diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypes.kt.193 b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypes.kt.193 new file mode 100644 index 00000000000..466ab209ae5 --- /dev/null +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypes.kt.193 @@ -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")) +} \ No newline at end of file diff --git a/idea/resources-en/messages/KotlinBundle.properties b/idea/resources-en/messages/KotlinBundle.properties index 857b44bc863..ed83745e44c 100644 --- a/idea/resources-en/messages/KotlinBundle.properties +++ b/idea/resources-en/messages/KotlinBundle.properties @@ -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 diff --git a/idea/resources-fir/META-INF/plugin.xml b/idea/resources-fir/META-INF/plugin.xml index 3dad1eb0338..abb1f81a657 100644 --- a/idea/resources-fir/META-INF/plugin.xml +++ b/idea/resources-fir/META-INF/plugin.xml @@ -209,6 +209,7 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu order="first"/> + - + ): 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")) -} diff --git a/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProvider.kt.193 b/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProvider.kt.193 deleted file mode 100644 index 859d2253b26..00000000000 --- a/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProvider.kt.193 +++ /dev/null @@ -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): 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")) -} diff --git a/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProviderImpl.kt b/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProviderImpl.kt new file mode 100644 index 00000000000..385c299d946 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinUsageTypeProviderImpl.kt @@ -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 { typeReference } != null -> SUPER_TYPE + + descriptor is ConstructorDescriptor && refExpr.getParentOfTypeAndBranch { typeReference } != null -> ANNOTATION + + with(refExpr.getParentOfTypeAndBranch { calleeExpression }) { + this?.calleeExpression is KtSimpleNameExpression + } -> if (descriptor is ConstructorDescriptor) CLASS_NEW_OPERATOR else FUNCTION_CALL + + refExpr.getParentOfTypeAndBranch { operationReference } != null || refExpr.getParentOfTypeAndBranch { operationReference } != null || refExpr.getParentOfTypeAndBranch { 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 + } + } +} \ No newline at end of file