Clean up findUsages package

This commit is contained in:
Nikolay Krasko
2019-03-19 15:59:38 +03:00
parent 046a35bcda
commit fdf2482600
12 changed files with 167 additions and 155 deletions
@@ -57,58 +57,58 @@ class KotlinElementDescriptionProvider : ElementDescriptionProvider {
} }
val internalSegments = generateSequence(this) { it.parentForFqName() } val internalSegments = generateSequence(this) { it.parentForFqName() }
.filterIsInstance<KtNamedDeclaration>() .filterIsInstance<KtNamedDeclaration>()
.map { it.name ?: "<no name provided>" } .map { it.name ?: "<no name provided>" }
.toList() .toList()
.asReversed() .asReversed()
val packageSegments = containingKtFile.packageFqName.pathSegments() val packageSegments = containingKtFile.packageFqName.pathSegments()
return FqNameUnsafe((packageSegments + internalSegments).joinToString(".")) return FqNameUnsafe((packageSegments + internalSegments).joinToString("."))
} }
private fun KtTypeReference.renderShort(): String { private fun KtTypeReference.renderShort(): String {
return accept( return accept(
object : KtVisitor<String, Unit>() { object : KtVisitor<String, Unit>() {
private val visitor get() = this private val visitor get() = this
override fun visitTypeReference(typeReference: KtTypeReference, data: Unit): String { override fun visitTypeReference(typeReference: KtTypeReference, data: Unit): String {
val typeText = typeReference.typeElement?.accept(this, data) ?: "???" val typeText = typeReference.typeElement?.accept(this, data) ?: "???"
return if (typeReference.hasParentheses()) "($typeText)" else typeText return if (typeReference.hasParentheses()) "($typeText)" else typeText
}
override fun visitDynamicType(type: KtDynamicType, data: Unit) = type.text
override fun visitFunctionType(type: KtFunctionType, data: Unit): String {
return buildString {
type.receiverTypeReference?.let { append(it.accept(visitor, data)).append('.') }
type.parameters.joinTo(this, prefix = "(", postfix = ")") { it.accept(visitor, data) }
append(" -> ")
append(type.returnTypeReference?.accept(visitor, data) ?: "???")
} }
}
override fun visitDynamicType(type: KtDynamicType, data: Unit) = type.text override fun visitNullableType(nullableType: KtNullableType, data: Unit): String {
val innerTypeText = nullableType.innerType?.accept(this, data) ?: return "???"
return "$innerTypeText?"
}
override fun visitFunctionType(type: KtFunctionType, data: Unit): String { override fun visitSelfType(type: KtSelfType, data: Unit) = type.text
return buildString {
type.receiverTypeReference?.let { append(it.accept(visitor, data)).append('.') }
type.parameters.joinTo(this, prefix = "(", postfix = ")") { it.accept(visitor, data) }
append(" -> ")
append(type.returnTypeReference?.accept(visitor, data) ?: "???")
}
}
override fun visitNullableType(nullableType: KtNullableType, data: Unit): String { override fun visitUserType(type: KtUserType, data: Unit): String {
val innerTypeText = nullableType.innerType?.accept(this, data) ?: return "???" return buildString {
return "$innerTypeText?" append(type.referencedName ?: "???")
}
override fun visitSelfType(type: KtSelfType, data: Unit) = type.text val arguments = type.typeArguments
if (arguments.isNotEmpty()) {
override fun visitUserType(type: KtUserType, data: Unit): String { arguments.joinTo(this, prefix = "<", postfix = ">") {
return buildString { it.typeReference?.accept(visitor, data) ?: it.text
append(type.referencedName ?: "???")
val arguments = type.typeArguments
if (arguments.isNotEmpty()) {
arguments.joinTo(this, prefix = "<", postfix = ">") {
it.typeReference?.accept(visitor, data) ?: it.text
}
} }
} }
} }
}
override fun visitParameter(parameter: KtParameter, data: Unit) = parameter.typeReference?.accept(this, data) ?: "???" override fun visitParameter(parameter: KtParameter, data: Unit) = parameter.typeReference?.accept(this, data) ?: "???"
}, },
Unit Unit
) )
} }
@@ -140,22 +140,27 @@ class KotlinElementDescriptionProvider : ElementDescriptionProvider {
targetElement.parent as? KtProperty targetElement.parent as? KtProperty
} else targetElement as? PsiNamedElement } else targetElement as? PsiNamedElement
@Suppress("FoldInitializerAndIfToElvis")
if (namedElement == null) { if (namedElement == null) {
return if (targetElement is KtElement) "'" + StringUtil.shortenTextWithEllipsis(targetElement.text.collapseSpaces(), 53, 0) + "'" else null return if (targetElement is KtElement) "'" + StringUtil.shortenTextWithEllipsis(
targetElement.text.collapseSpaces(),
53,
0
) + "'" else null
} }
if (namedElement.language != KotlinLanguage.INSTANCE) return null if (namedElement.language != KotlinLanguage.INSTANCE) return null
return when(location) { return when (location) {
is UsageViewTypeLocation -> elementKind() is UsageViewTypeLocation -> elementKind()
is UsageViewShortNameLocation, is UsageViewLongNameLocation -> namedElement.name is UsageViewShortNameLocation, is UsageViewLongNameLocation -> namedElement.name
is RefactoringDescriptionLocation -> { is RefactoringDescriptionLocation -> {
val kind = elementKind() ?: return null val kind = elementKind() ?: return null
if (namedElement !is KtNamedDeclaration) return null if (namedElement !is KtNamedDeclaration) return null
val renderFqName = location.includeParent() && val renderFqName = location.includeParent() &&
namedElement !is KtTypeParameter && namedElement !is KtTypeParameter &&
namedElement !is KtParameter && namedElement !is KtParameter &&
namedElement !is KtConstructor<*> namedElement !is KtConstructor<*>
val desc = when (namedElement) { val desc = when (namedElement) {
is KtFunction -> { is KtFunction -> {
val baseText = buildString { val baseText = buildString {
@@ -166,7 +171,7 @@ class KotlinElementDescriptionProvider : ElementDescriptionProvider {
namedElement.receiverTypeReference?.let { append(" on ").append(it.renderShort()) } namedElement.receiverTypeReference?.let { append(" on ").append(it.renderShort()) }
} }
val parentFqName = if (renderFqName) namedElement.fqName().parent() else null val parentFqName = if (renderFqName) namedElement.fqName().parent() else null
if (parentFqName?.isRoot ?: true) baseText else "${parentFqName!!.asString()}.$baseText" if (parentFqName?.isRoot != false) baseText else "${parentFqName.asString()}.$baseText"
} }
else -> (if (renderFqName) namedElement.fqName().asString() else namedElement.name) ?: "" else -> (if (renderFqName) namedElement.fqName().asString() else namedElement.name) ?: ""
} }
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinTypeParameterFindUsag
import org.jetbrains.kotlin.idea.refactoring.checkSuperMethods import org.jetbrains.kotlin.idea.refactoring.checkSuperMethods
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parameterIndex import org.jetbrains.kotlin.psi.psiUtil.parameterIndex
import java.lang.IllegalArgumentException
class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactory() { class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactory() {
val javaHandlerFactory = JavaFindUsagesHandlerFactory(project) val javaHandlerFactory = JavaFindUsagesHandlerFactory(project)
@@ -47,12 +46,12 @@ class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactor
val defaultOptions = FindUsagesOptions(project) val defaultOptions = FindUsagesOptions(project)
override fun canFindUsages(element: PsiElement): Boolean = override fun canFindUsages(element: PsiElement): Boolean =
element is KtClassOrObject || element is KtClassOrObject ||
element is KtNamedFunction || element is KtNamedFunction ||
element is KtProperty || element is KtProperty ||
element is KtParameter || element is KtParameter ||
element is KtTypeParameter || element is KtTypeParameter ||
element is KtConstructor<*> element is KtConstructor<*>
override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler { override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler {
when (element) { when (element) {
@@ -114,8 +113,7 @@ class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactor
val target = declarations.single().unwrapped ?: return FindUsagesHandler.NULL_HANDLER val target = declarations.single().unwrapped ?: return FindUsagesHandler.NULL_HANDLER
if (target is KtNamedDeclaration) { if (target is KtNamedDeclaration) {
KotlinFindMemberUsagesHandler.getInstance(target, factory = this) KotlinFindMemberUsagesHandler.getInstance(target, factory = this)
} } else {
else {
javaHandlerFactory.createFindUsagesHandler(target, false)!! javaHandlerFactory.createFindUsagesHandler(target, false)!!
} }
} }
@@ -125,10 +123,12 @@ class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandlerFactor
} }
private fun askWhetherShouldSearchForParameterInOverridingMethods(parameter: KtParameter): Boolean { private fun askWhetherShouldSearchForParameterInOverridingMethods(parameter: KtParameter): Boolean {
return Messages.showOkCancelDialog(parameter.project, return Messages.showOkCancelDialog(
FindBundle.message("find.parameter.usages.in.overriding.methods.prompt", parameter.name), parameter.project,
FindBundle.message("find.parameter.usages.in.overriding.methods.title"), FindBundle.message("find.parameter.usages.in.overriding.methods.prompt", parameter.name),
CommonBundle.getYesButtonText(), CommonBundle.getNoButtonText(), FindBundle.message("find.parameter.usages.in.overriding.methods.title"),
Messages.getQuestionIcon()) == Messages.OK CommonBundle.getYesButtonText(), CommonBundle.getNoButtonText(),
Messages.getQuestionIcon()
) == Messages.OK
} }
} }
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.findUsages
import com.intellij.psi.PsiReference import com.intellij.psi.PsiReference
import com.intellij.usageView.UsageInfo import com.intellij.usageView.UsageInfo
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
class KotlinReferenceUsageInfo(reference: PsiReference) : UsageInfo(reference) { class KotlinReferenceUsageInfo(reference: PsiReference) : UsageInfo(reference) {
private val referenceType = reference::class.java private val referenceType = reference::class.java
@@ -31,7 +31,7 @@ object KotlinUsageTypeProvider : UsageTypeProviderEx {
return convertEnumToUsageType(usageType) return convertEnumToUsageType(usageType)
} }
fun convertEnumToUsageType(usageType: UsageTypeEnum): UsageType = when (usageType) { private fun convertEnumToUsageType(usageType: UsageTypeEnum): UsageType = when (usageType) {
TYPE_CONSTRAINT -> KotlinUsageTypes.TYPE_CONSTRAINT TYPE_CONSTRAINT -> KotlinUsageTypes.TYPE_CONSTRAINT
VALUE_PARAMETER_TYPE -> KotlinUsageTypes.VALUE_PARAMETER_TYPE VALUE_PARAMETER_TYPE -> KotlinUsageTypes.VALUE_PARAMETER_TYPE
NON_LOCAL_PROPERTY_TYPE -> KotlinUsageTypes.NON_LOCAL_PROPERTY_TYPE NON_LOCAL_PROPERTY_TYPE -> KotlinUsageTypes.NON_LOCAL_PROPERTY_TYPE
@@ -85,7 +85,6 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
: klass.isAnnotation() : klass.isAnnotation()
? factory.createAnnotationType(name) ? factory.createAnnotationType(name)
: factory.createInterface(name); : factory.createInterface(name);
} }
else { else {
javaClass = factory.createClass(name); javaClass = factory.createClass(name);
@@ -172,7 +171,6 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
false false
); );
} }
} }
@Override @Override
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.findUsages.dialogs;
import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleColoredComponent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.idea.search.usagesSearch.UtilsKt; import org.jetbrains.kotlin.idea.search.usagesSearch.UtilsKt;
import org.jetbrains.kotlin.psi.KtNamedDeclaration; import org.jetbrains.kotlin.psi.KtNamedDeclaration;
import org.jetbrains.kotlin.renderer.DescriptorRenderer; import org.jetbrains.kotlin.renderer.DescriptorRenderer;
@@ -31,8 +32,12 @@ class Utils {
public static void configureLabelComponent( public static void configureLabelComponent(
@NotNull SimpleColoredComponent coloredComponent, @NotNull SimpleColoredComponent coloredComponent,
@NotNull KtNamedDeclaration declaration) { @NotNull KtNamedDeclaration declaration
coloredComponent.append(DescriptorRenderer.COMPACT.render(UtilsKt.getDescriptor(declaration))); ) {
DeclarationDescriptor descriptor = UtilsKt.getDescriptor(declaration);
if (descriptor != null) {
coloredComponent.append(DescriptorRenderer.COMPACT.render(descriptor));
}
} }
static boolean renameCheckbox(@NotNull JPanel panel, @NotNull String srcText, @NotNull String destText) { static boolean renameCheckbox(@NotNull JPanel panel, @NotNull String srcText, @NotNull String destText) {
@@ -49,17 +54,15 @@ class Utils {
return false; return false;
} }
static boolean removeCheckbox(@NotNull JPanel panel, @NotNull String srcText) { static void removeCheckbox(@NotNull JPanel panel, @NotNull String srcText) {
for (Component component : panel.getComponents()) { for (Component component : panel.getComponents()) {
if (component instanceof JCheckBox) { if (component instanceof JCheckBox) {
JCheckBox checkBox = (JCheckBox) component; JCheckBox checkBox = (JCheckBox) component;
if (checkBox.getText().equals(srcText)) { if (checkBox.getText().equals(srcText)) {
panel.remove(checkBox); panel.remove(checkBox);
return true; return;
} }
} }
} }
return false;
} }
} }
@@ -36,8 +36,8 @@ import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
fun PsiElement.processAllExactUsages( fun PsiElement.processAllExactUsages(
options: () -> FindUsagesOptions, options: () -> FindUsagesOptions,
processor: (UsageInfo) -> Unit processor: (UsageInfo) -> Unit
) { ) {
fun elementsToCheckReferenceAgainst(reference: PsiReference): List<PsiElement> { fun elementsToCheckReferenceAgainst(reference: PsiReference): List<PsiElement> {
if (reference is KtReference || this !is KtDeclaration) return listOf(this) if (reference is KtReference || this !is KtDeclaration) return listOf(this)
@@ -52,32 +52,32 @@ fun PsiElement.processAllExactUsages(
val project = project val project = project
FindUsagesManager(project, UsageViewManager.getInstance(project)) FindUsagesManager(project, UsageViewManager.getInstance(project))
.getFindUsagesHandler(this, true) .getFindUsagesHandler(this, true)
?.processElementUsages( ?.processElementUsages(
this, this,
{ { usageInfo ->
val reference = it.reference ?: return@processElementUsages true val reference = usageInfo.reference ?: return@processElementUsages true
if (reference is LightMemberReference || elementsToCheckReferenceAgainst(reference).any { reference.isReferenceTo(it) }) { if (reference is LightMemberReference || elementsToCheckReferenceAgainst(reference).any { reference.isReferenceTo(it) }) {
processor(it) processor(usageInfo)
} }
true true
}, },
options() options()
) )
} }
fun KtDeclaration.processAllUsages( fun KtDeclaration.processAllUsages(
options: FindUsagesOptions, options: FindUsagesOptions,
processor: (UsageInfo) -> Unit processor: (UsageInfo) -> Unit
) { ) {
val findUsagesHandler = KotlinFindUsagesHandlerFactory(project).createFindUsagesHandler(this, true) val findUsagesHandler = KotlinFindUsagesHandlerFactory(project).createFindUsagesHandler(this, true)
findUsagesHandler.processElementUsages( findUsagesHandler.processElementUsages(
this, this,
{ {
processor(it) processor(it)
true true
}, },
options options
) )
} }
@@ -26,20 +26,21 @@ import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiParameter import com.intellij.psi.PsiParameter
import com.intellij.usageView.UsageInfo import com.intellij.usageView.UsageInfo
import com.intellij.util.Processor import com.intellij.util.Processor
import org.jetbrains.kotlin.idea.findUsages.* import org.jetbrains.kotlin.idea.findUsages.KotlinCallableFindUsagesOptions
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtNamedDeclaration
class DelegatingFindMemberUsagesHandler( class DelegatingFindMemberUsagesHandler(
val declaration: KtNamedDeclaration, val declaration: KtNamedDeclaration,
val elementsToSearch: Collection<PsiElement>, private val elementsToSearch: Collection<PsiElement>,
val factory: KotlinFindUsagesHandlerFactory val factory: KotlinFindUsagesHandlerFactory
) : FindUsagesHandler(declaration) { ) : FindUsagesHandler(declaration) {
private val kotlinHandler = KotlinFindMemberUsagesHandler.getInstance(declaration, elementsToSearch, factory) private val kotlinHandler = KotlinFindMemberUsagesHandler.getInstance(declaration, elementsToSearch, factory)
private data class HandlerAndOptions( private data class HandlerAndOptions(
val handler: FindUsagesHandler, val handler: FindUsagesHandler,
val options: FindUsagesOptions? val options: FindUsagesOptions?
) )
private fun getHandlerAndOptions(element: PsiElement, options: FindUsagesOptions?): HandlerAndOptions? { private fun getHandlerAndOptions(element: PsiElement, options: FindUsagesOptions?): HandlerAndOptions? {
@@ -48,8 +49,10 @@ class DelegatingFindMemberUsagesHandler(
HandlerAndOptions(KotlinFindMemberUsagesHandler.getInstance(element, elementsToSearch, factory), options) HandlerAndOptions(KotlinFindMemberUsagesHandler.getInstance(element, elementsToSearch, factory), options)
is PsiMethod, is PsiParameter -> is PsiMethod, is PsiParameter ->
HandlerAndOptions(JavaFindUsagesHandler(element, elementsToSearch.toTypedArray(), factory.javaHandlerFactory), HandlerAndOptions(
(options as KotlinCallableFindUsagesOptions?)?.toJavaOptions(project)) JavaFindUsagesHandler(element, elementsToSearch.toTypedArray(), factory.javaHandlerFactory),
(options as KotlinCallableFindUsagesOptions?)?.toJavaOptions(project)
)
else -> null else -> null
} }
@@ -57,7 +60,7 @@ class DelegatingFindMemberUsagesHandler(
override fun getFindUsagesDialog(isSingleFile: Boolean, toShowInNewTab: Boolean, mustOpenInNewTab: Boolean): AbstractFindUsagesDialog { override fun getFindUsagesDialog(isSingleFile: Boolean, toShowInNewTab: Boolean, mustOpenInNewTab: Boolean): AbstractFindUsagesDialog {
return getHandlerAndOptions(psiElement, null)?.handler?.getFindUsagesDialog(isSingleFile, toShowInNewTab, mustOpenInNewTab) return getHandlerAndOptions(psiElement, null)?.handler?.getFindUsagesDialog(isSingleFile, toShowInNewTab, mustOpenInNewTab)
?: super.getFindUsagesDialog(isSingleFile, toShowInNewTab, mustOpenInNewTab) ?: super.getFindUsagesDialog(isSingleFile, toShowInNewTab, mustOpenInNewTab)
} }
override fun getPrimaryElements(): Array<PsiElement> { override fun getPrimaryElements(): Array<PsiElement> {
@@ -54,19 +54,21 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
import java.util.* import java.util.*
class KotlinFindClassUsagesHandler( class KotlinFindClassUsagesHandler(
ktClass: KtClassOrObject, ktClass: KtClassOrObject,
factory: KotlinFindUsagesHandlerFactory factory: KotlinFindUsagesHandlerFactory
) : KotlinFindUsagesHandler<KtClassOrObject>(ktClass, factory) { ) : KotlinFindUsagesHandler<KtClassOrObject>(ktClass, factory) {
override fun getFindUsagesDialog( override fun getFindUsagesDialog(
isSingleFile: Boolean, toShowInNewTab: Boolean, mustOpenInNewTab: Boolean isSingleFile: Boolean, toShowInNewTab: Boolean, mustOpenInNewTab: Boolean
): AbstractFindUsagesDialog { ): AbstractFindUsagesDialog {
return KotlinFindClassUsagesDialog(getElement(), return KotlinFindClassUsagesDialog(
project, getElement(),
factory.findClassOptions, project,
toShowInNewTab, factory.findClassOptions,
mustOpenInNewTab, toShowInNewTab,
isSingleFile, mustOpenInNewTab,
this) isSingleFile,
this
)
} }
override fun createSearcher(element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions): Searcher { override fun createSearcher(element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions): Searcher {
@@ -74,11 +76,11 @@ class KotlinFindClassUsagesHandler(
} }
private class MySearcher( private class MySearcher(
element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions
) : Searcher(element, processor, options) { ) : Searcher(element, processor, options) {
private val kotlinOptions = options as KotlinClassFindUsagesOptions private val kotlinOptions = options as KotlinClassFindUsagesOptions
private val referenceProcessor = KotlinFindUsagesHandler.createReferenceProcessor(processor) private val referenceProcessor = createReferenceProcessor(processor)
override fun buildTaskList(): Boolean { override fun buildTaskList(): Boolean {
val classOrObject = element as KtClassOrObject val classOrObject = element as KtClassOrObject
@@ -91,7 +93,7 @@ class KotlinFindClassUsagesHandler(
processMemberReferencesLater(classOrObject) processMemberReferencesLater(classOrObject)
} }
if (kotlinOptions.isUsages && classOrObject is KtObjectDeclaration && classOrObject.isCompanion() && classOrObject in options.searchScope ) { if (kotlinOptions.isUsages && classOrObject is KtObjectDeclaration && classOrObject.isCompanion() && classOrObject in options.searchScope) {
if (!processCompanionObjectInternalReferences(classOrObject)) return false if (!processCompanionObjectInternalReferences(classOrObject)) return false
} }
@@ -117,19 +119,20 @@ class KotlinFindClassUsagesHandler(
val request = HierarchySearchRequest(element, options.searchScope, kotlinOptions.isCheckDeepInheritance) val request = HierarchySearchRequest(element, options.searchScope, kotlinOptions.isCheckDeepInheritance)
addTask { addTask {
request.searchInheritors().forEach( request.searchInheritors().forEach(
PsiElementProcessorAdapter( PsiElementProcessorAdapter(
PsiElementProcessor<PsiClass> { element -> PsiElementProcessor<PsiClass> { element ->
runReadAction { runReadAction {
if (!element.isValid) return@runReadAction false if (!element.isValid) return@runReadAction false
val isInterface = element.isInterface val isInterface = element.isInterface
when { when {
isInterface && kotlinOptions.isDerivedInterfaces || !isInterface && kotlinOptions.isDerivedClasses -> isInterface && kotlinOptions.isDerivedInterfaces || !isInterface && kotlinOptions.isDerivedClasses ->
KotlinFindUsagesHandler.processUsage(processor, element.navigationElement) processUsage(processor, element.navigationElement)
else -> true
} else -> true
}
} }
) }
}
)
) )
} }
} }
@@ -160,14 +163,15 @@ class KotlinFindClassUsagesHandler(
private fun processCompanionObjectInternalReferences(companionObject: KtObjectDeclaration): Boolean { private fun processCompanionObjectInternalReferences(companionObject: KtObjectDeclaration): Boolean {
val klass = companionObject.getStrictParentOfType<KtClass>() ?: return true val klass = companionObject.getStrictParentOfType<KtClass>() ?: return true
val companionObjectDescriptor = companionObject.descriptor val companionObjectDescriptor = companionObject.descriptor
return !klass.anyDescendantOfType<KtElement>(fun (element: KtElement): Boolean { return !klass.anyDescendantOfType(fun(element: KtElement): Boolean {
if (element == companionObject) return false // skip companion object itself if (element == companionObject) return false // skip companion object itself
val bindingContext = element.analyze() val bindingContext = element.analyze()
val resolvedCall = bindingContext[BindingContext.CALL, element]?.getResolvedCall(bindingContext) ?: return false val resolvedCall = bindingContext[BindingContext.CALL, element]?.getResolvedCall(bindingContext) ?: return false
if ((resolvedCall.dispatchReceiver as? ImplicitClassReceiver)?.declarationDescriptor == companionObjectDescriptor if ((resolvedCall.dispatchReceiver as? ImplicitClassReceiver)?.declarationDescriptor == companionObjectDescriptor
|| (resolvedCall.extensionReceiver as? ImplicitClassReceiver)?.declarationDescriptor == companionObjectDescriptor) { || (resolvedCall.extensionReceiver as? ImplicitClassReceiver)?.declarationDescriptor == companionObjectDescriptor
return element.references.any { !referenceProcessor.process(it) } ) {
return element.references.any { !referenceProcessor.process(it) }
} }
return false return false
}) })
@@ -176,7 +180,8 @@ class KotlinFindClassUsagesHandler(
private fun processMemberReferencesLater(classOrObject: KtClassOrObject) { private fun processMemberReferencesLater(classOrObject: KtClassOrObject) {
for (declaration in classOrObject.effectiveDeclarations()) { for (declaration in classOrObject.effectiveDeclarations()) {
if ((declaration is KtNamedFunction && kotlinOptions.isMethodsUsages) || if ((declaration is KtNamedFunction && kotlinOptions.isMethodsUsages) ||
((declaration is KtProperty || declaration is KtParameter) && kotlinOptions.isFieldsUsages)) { ((declaration is KtProperty || declaration is KtParameter) && kotlinOptions.isFieldsUsages)
) {
addTask { ReferencesSearch.search(declaration, options.searchScope).forEach(referenceProcessor) } addTask { ReferencesSearch.search(declaration, options.searchScope).forEach(referenceProcessor) }
} }
} }
@@ -185,10 +190,10 @@ class KotlinFindClassUsagesHandler(
override fun getStringsToSearch(element: PsiElement): Collection<String> { override fun getStringsToSearch(element: PsiElement): Collection<String> {
val psiClass = when (element) { val psiClass = when (element) {
is PsiClass -> element is PsiClass -> element
is KtClassOrObject -> getElement().toLightClass() is KtClassOrObject -> getElement().toLightClass()
else -> null else -> null
} ?: return Collections.emptyList() } ?: return Collections.emptyList()
return JavaFindUsagesHelper.getElementNames(psiClass) return JavaFindUsagesHelper.getElementNames(psiClass)
} }
@@ -135,8 +135,7 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration> protected c
val detector = KotlinReadWriteAccessDetector() val detector = KotlinReadWriteAccessDetector()
return FilteredQuery(result) { return FilteredQuery(result) {
val access = detector.getReferenceAccess(element, it) when (detector.getReferenceAccess(element, it)) {
when (access) {
ReadWriteAccessDetector.Access.Read -> kotlinOptions.isReadAccess ReadWriteAccessDetector.Access.Read -> kotlinOptions.isReadAccess
ReadWriteAccessDetector.Access.Write -> kotlinOptions.isWriteAccess ReadWriteAccessDetector.Access.Write -> kotlinOptions.isWriteAccess
ReadWriteAccessDetector.Access.ReadWrite -> kotlinOptions.isReadWriteAccess ReadWriteAccessDetector.Access.ReadWrite -> kotlinOptions.isReadWriteAccess
@@ -168,7 +167,7 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration> protected c
private val kotlinOptions = options as KotlinCallableFindUsagesOptions private val kotlinOptions = options as KotlinCallableFindUsagesOptions
override fun buildTaskList(): Boolean { override fun buildTaskList(): Boolean {
val referenceProcessor = KotlinFindUsagesHandler.createReferenceProcessor(processor) val referenceProcessor = createReferenceProcessor(processor)
val uniqueProcessor = CommonProcessors.UniqueProcessor(processor) val uniqueProcessor = CommonProcessors.UniqueProcessor(processor)
if (options.isUsages) { if (options.isUsages) {
@@ -202,7 +201,7 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration> protected c
val overriders = HierarchySearchRequest(element, options.searchScope, true).searchOverriders() val overriders = HierarchySearchRequest(element, options.searchScope, true).searchOverriders()
overriders.all { overriders.all {
val element = runReadAction { it.takeIf { it.isValid }?.navigationElement } ?: return@all true val element = runReadAction { it.takeIf { it.isValid }?.navigationElement } ?: return@all true
KotlinFindUsagesHandler.processUsage(uniqueProcessor, element) processUsage(uniqueProcessor, element)
} }
} }
} }
@@ -34,12 +34,14 @@ import org.jetbrains.kotlin.idea.findUsages.KotlinReferenceUsageInfo
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
import java.util.* import java.util.*
abstract class KotlinFindUsagesHandler<T : PsiElement>(psiElement: T, abstract class KotlinFindUsagesHandler<T : PsiElement>(
private val elementsToSearch: Collection<PsiElement>, psiElement: T,
val factory: KotlinFindUsagesHandlerFactory) private val elementsToSearch: Collection<PsiElement>,
: FindUsagesHandler(psiElement) { val factory: KotlinFindUsagesHandlerFactory
) : FindUsagesHandler(psiElement) {
@Suppress("UNCHECKED_CAST") fun getElement(): T { @Suppress("UNCHECKED_CAST")
fun getElement(): T {
return psiElement as T return psiElement as T
} }
@@ -52,7 +54,7 @@ abstract class KotlinFindUsagesHandler<T : PsiElement>(psiElement: T,
elementsToSearch.toTypedArray() elementsToSearch.toTypedArray()
} }
protected fun searchTextOccurrences(element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions): Boolean { private fun searchTextOccurrences(element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions): Boolean {
if (!options.isSearchForTextOccurrences) return false if (!options.isSearchForTextOccurrences) return false
val scope = options.searchScope val scope = options.searchScope
@@ -72,7 +74,7 @@ abstract class KotlinFindUsagesHandler<T : PsiElement>(psiElement: T,
return searchReferences(element, processor, options) && searchTextOccurrences(element, processor, options) return searchReferences(element, processor, options) && searchTextOccurrences(element, processor, options)
} }
protected fun searchReferences(element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions): Boolean { private fun searchReferences(element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions): Boolean {
val searcher = createSearcher(element, processor, options) val searcher = createSearcher(element, processor, options)
if (!DumbService.getInstance(element.project).runReadActionInSmartMode<Boolean> { searcher.buildTaskList() }) return false if (!DumbService.getInstance(element.project).runReadActionInSmartMode<Boolean> { searcher.buildTaskList() }) return false
return searcher.executeTasks() return searcher.executeTasks()
@@ -84,14 +86,12 @@ abstract class KotlinFindUsagesHandler<T : PsiElement>(psiElement: T,
val results = Collections.synchronizedList(arrayListOf<PsiReference>()) val results = Collections.synchronizedList(arrayListOf<PsiReference>())
val options = findUsagesOptions.clone() val options = findUsagesOptions.clone()
options.searchScope = searchScope options.searchScope = searchScope
searchReferences(target, object : Processor<UsageInfo> { searchReferences(target, Processor { info ->
override fun process(info: UsageInfo): Boolean { val reference = info.reference
val reference = info.reference if (reference != null) {
if (reference != null) { results.add(reference)
results.add(reference)
}
return true
} }
true
}, options) }, options)
return results return results
} }
@@ -142,7 +142,7 @@ abstract class KotlinFindUsagesHandler<T : PsiElement>(psiElement: T,
internal fun createReferenceProcessor(usageInfoProcessor: Processor<UsageInfo>): Processor<PsiReference> { internal fun createReferenceProcessor(usageInfoProcessor: Processor<UsageInfo>): Processor<PsiReference> {
val uniqueProcessor = CommonProcessors.UniqueProcessor(usageInfoProcessor) val uniqueProcessor = CommonProcessors.UniqueProcessor(usageInfoProcessor)
return Processor { KotlinFindUsagesHandler.processUsage(uniqueProcessor, it) } return Processor { processUsage(uniqueProcessor, it) }
} }
} }
} }
@@ -28,22 +28,22 @@ import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinTypeParameterFindUsage
import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtNamedDeclaration
class KotlinTypeParameterFindUsagesHandler( class KotlinTypeParameterFindUsagesHandler(
element: KtNamedDeclaration, element: KtNamedDeclaration,
factory: KotlinFindUsagesHandlerFactory factory: KotlinFindUsagesHandlerFactory
) : KotlinFindUsagesHandler<KtNamedDeclaration>(element, factory) { ) : KotlinFindUsagesHandler<KtNamedDeclaration>(element, factory) {
override fun getFindUsagesDialog( override fun getFindUsagesDialog(
isSingleFile: Boolean, toShowInNewTab: Boolean, mustOpenInNewTab: Boolean isSingleFile: Boolean, toShowInNewTab: Boolean, mustOpenInNewTab: Boolean
): AbstractFindUsagesDialog { ): AbstractFindUsagesDialog {
return KotlinTypeParameterFindUsagesDialog<KtNamedDeclaration>( return KotlinTypeParameterFindUsagesDialog<KtNamedDeclaration>(
getElement(), project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, this getElement(), project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, this
) )
} }
override fun createSearcher(element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions): Searcher { override fun createSearcher(element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions): Searcher {
return object: Searcher(element, processor, options) { return object : Searcher(element, processor, options) {
override fun buildTaskList(): Boolean { override fun buildTaskList(): Boolean {
addTask { addTask {
ReferencesSearch.search(element, options.searchScope).all { KotlinFindUsagesHandler.processUsage(processor, it ) } ReferencesSearch.search(element, options.searchScope).all { processUsage(processor, it) }
} }
return true return true
} }