Do not run search for operator-like names in inspections
It might be rather expensive to search componentN's usages in the whole project
This commit is contained in:
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.search
|
|||||||
|
|
||||||
import com.intellij.openapi.fileTypes.FileType
|
import com.intellij.openapi.fileTypes.FileType
|
||||||
import com.intellij.openapi.fileTypes.FileTypeRegistry
|
import com.intellij.openapi.fileTypes.FileTypeRegistry
|
||||||
|
import com.intellij.openapi.progress.ProgressIndicator
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
@@ -27,7 +28,9 @@ import com.intellij.psi.search.PsiSearchHelper
|
|||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
|
|
||||||
infix fun SearchScope.and(otherScope: SearchScope): SearchScope = intersectWith(otherScope)
|
infix fun SearchScope.and(otherScope: SearchScope): SearchScope = intersectWith(otherScope)
|
||||||
infix fun SearchScope.or(otherScope: SearchScope): SearchScope = union(otherScope)
|
infix fun SearchScope.or(otherScope: SearchScope): SearchScope = union(otherScope)
|
||||||
@@ -97,3 +100,14 @@ fun ReferencesSearch.SearchParameters.effectiveSearchScope(element: PsiElement):
|
|||||||
fun isOnlyKotlinSearch(searchScope: SearchScope): Boolean {
|
fun isOnlyKotlinSearch(searchScope: SearchScope): Boolean {
|
||||||
return searchScope is LocalSearchScope && searchScope.scope.all { it.containingFile is KtFile }
|
return searchScope is LocalSearchScope && searchScope.scope.all { it.containingFile is KtFile }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PsiSearchHelper.isCheapEnoughToSearchConsideringOperators(
|
||||||
|
name: String,
|
||||||
|
scope: GlobalSearchScope,
|
||||||
|
fileToIgnoreOccurrencesIn: PsiFile?,
|
||||||
|
progress: ProgressIndicator?
|
||||||
|
): PsiSearchHelper.SearchCostResult {
|
||||||
|
if (OperatorConventions.isConventionName(Name.identifier(name))) return PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES
|
||||||
|
|
||||||
|
return isCheapEnoughToSearch(name, scope, fileToIgnoreOccurrencesIn, progress)
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import com.intellij.psi.search.searches.ReferencesSearch
|
|||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import org.jetbrains.kotlin.idea.quickfix.RemoveValVarFromParameterFix
|
import org.jetbrains.kotlin.idea.quickfix.RemoveValVarFromParameterFix
|
||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
|
import org.jetbrains.kotlin.idea.search.isCheapEnoughToSearchConsideringOperators
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.getAccessorNames
|
import org.jetbrains.kotlin.idea.search.usagesSearch.getAccessorNames
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -92,7 +93,7 @@ class CanBeParameterInspection : AbstractKotlinInspection() {
|
|||||||
if (useScope is GlobalSearchScope) {
|
if (useScope is GlobalSearchScope) {
|
||||||
val psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(parameter.project)
|
val psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(parameter.project)
|
||||||
for (accessorName in parameter.getAccessorNames()) {
|
for (accessorName in parameter.getAccessorNames()) {
|
||||||
when (psiSearchHelper.isCheapEnoughToSearch(accessorName, useScope, null, null)) {
|
when (psiSearchHelper.isCheapEnoughToSearchConsideringOperators(accessorName, useScope, null, null)) {
|
||||||
ZERO_OCCURRENCES -> {
|
ZERO_OCCURRENCES -> {
|
||||||
} // go on
|
} // go on
|
||||||
else -> return // accessor in use: should remain a property
|
else -> return // accessor in use: should remain a property
|
||||||
@@ -100,7 +101,7 @@ class CanBeParameterInspection : AbstractKotlinInspection() {
|
|||||||
}
|
}
|
||||||
// TOO_MANY_OCCURRENCES: too expensive
|
// TOO_MANY_OCCURRENCES: too expensive
|
||||||
// ZERO_OCCURRENCES: unused at all, reported elsewhere
|
// ZERO_OCCURRENCES: unused at all, reported elsewhere
|
||||||
if (psiSearchHelper.isCheapEnoughToSearch(name, useScope, null, null) != FEW_OCCURRENCES) return
|
if (psiSearchHelper.isCheapEnoughToSearchConsideringOperators(name, useScope, null, null) != FEW_OCCURRENCES) return
|
||||||
}
|
}
|
||||||
// Find all references and check them
|
// Find all references and check them
|
||||||
val references = ReferencesSearch.search(parameter, useScope)
|
val references = ReferencesSearch.search(parameter, useScope)
|
||||||
|
|||||||
+6
-4
@@ -31,17 +31,19 @@ import com.intellij.util.Processor
|
|||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.effectiveVisibility
|
import org.jetbrains.kotlin.descriptors.effectiveVisibility
|
||||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.core.isInheritable
|
import org.jetbrains.kotlin.idea.core.isInheritable
|
||||||
import org.jetbrains.kotlin.idea.core.isOverridable
|
import org.jetbrains.kotlin.idea.core.isOverridable
|
||||||
|
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||||
import org.jetbrains.kotlin.idea.quickfix.AddModifierFix
|
import org.jetbrains.kotlin.idea.quickfix.AddModifierFix
|
||||||
import org.jetbrains.kotlin.idea.refactoring.isConstructorDeclaredProperty
|
import org.jetbrains.kotlin.idea.refactoring.isConstructorDeclaredProperty
|
||||||
|
import org.jetbrains.kotlin.idea.search.isCheapEnoughToSearchConsideringOperators
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmFieldAnnotation
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.isPrivate
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmFieldAnnotation
|
||||||
|
|
||||||
class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() {
|
class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() {
|
||||||
|
|
||||||
@@ -96,7 +98,7 @@ class MemberVisibilityCanPrivateInspection : AbstractKotlinInspection() {
|
|||||||
val useScope = declaration.useScope
|
val useScope = declaration.useScope
|
||||||
val name = declaration.name ?: return false
|
val name = declaration.name ?: return false
|
||||||
if (useScope is GlobalSearchScope) {
|
if (useScope is GlobalSearchScope) {
|
||||||
when (psiSearchHelper.isCheapEnoughToSearch(name, useScope, null, null)) {
|
when (psiSearchHelper.isCheapEnoughToSearchConsideringOperators(name, useScope, null, null)) {
|
||||||
PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES -> return false
|
PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES -> return false
|
||||||
PsiSearchHelper.SearchCostResult.ZERO_OCCURRENCES -> return false
|
PsiSearchHelper.SearchCostResult.ZERO_OCCURRENCES -> return false
|
||||||
PsiSearchHelper.SearchCostResult.FEW_OCCURRENCES -> {
|
PsiSearchHelper.SearchCostResult.FEW_OCCURRENCES -> {
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ import org.jetbrains.kotlin.idea.imports.importableFqName
|
|||||||
import org.jetbrains.kotlin.idea.quickfix.RemoveUnusedFunctionParameterFix
|
import org.jetbrains.kotlin.idea.quickfix.RemoveUnusedFunctionParameterFix
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||||
|
import org.jetbrains.kotlin.idea.search.isCheapEnoughToSearchConsideringOperators
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
|
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.getAccessorNames
|
import org.jetbrains.kotlin.idea.search.usagesSearch.getAccessorNames
|
||||||
@@ -205,7 +206,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
|
|||||||
|
|
||||||
for (name in listOf(declaration.name) + declaration.getAccessorNames() + listOfNotNull(declaration.getClassNameForCompanionObject())) {
|
for (name in listOf(declaration.name) + declaration.getAccessorNames() + listOfNotNull(declaration.getClassNameForCompanionObject())) {
|
||||||
if (name == null) continue
|
if (name == null) continue
|
||||||
when (psiSearchHelper.isCheapEnoughToSearch(name, useScope, null, null)) {
|
when (psiSearchHelper.isCheapEnoughToSearchConsideringOperators(name, useScope, null, null)) {
|
||||||
ZERO_OCCURRENCES -> {} // go on, check other names
|
ZERO_OCCURRENCES -> {} // go on, check other names
|
||||||
FEW_OCCURRENCES -> zeroOccurrences = false
|
FEW_OCCURRENCES -> zeroOccurrences = false
|
||||||
TOO_MANY_OCCURRENCES -> return true // searching usages is too expensive; behave like it is used
|
TOO_MANY_OCCURRENCES -> return true // searching usages is too expensive; behave like it is used
|
||||||
|
|||||||
Reference in New Issue
Block a user