From a67dd3c1128519c98bbb196f0c54f340b62c25d8 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 12 Sep 2024 17:54:40 +0200 Subject: [PATCH] ignore usages in scripts in k2 (part of KTIJ-27513 K2 IDE: Slow reference search for specific symbols in unused symbol inspection) GitOrigin-RevId: 1232ce359bcb0c2cd6f8f340607e63abba6683b9 --- .../idea/search/KotlinSearchUsagesSupport.kt | 1 + .../kotlin/idea/search/searchUtil.kt | 26 ---------------- .../idea/highlighting/K2UnusedSymbolUtil.kt | 4 +-- .../inspections/UnusedSymbolInspection.kt | 6 ++-- .../search/KotlinSearchUsagesSupportImpl.kt | 30 ++++++++++++++++++- .../kotlin/idea/search/usagesSearch/utils.kt | 1 - .../usages/KotlinK2SearchUsagesSupport.kt | 4 +++ 7 files changed, 40 insertions(+), 32 deletions(-) diff --git a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/KotlinSearchUsagesSupport.kt b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/KotlinSearchUsagesSupport.kt index 0f0dc630d875..8d132570fbd4 100644 --- a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/KotlinSearchUsagesSupport.kt +++ b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/KotlinSearchUsagesSupport.kt @@ -138,6 +138,7 @@ interface KotlinSearchUsagesSupport { fun forceResolveReferences(file: KtFile, elements: List) fun scriptDefinitionExists(file: PsiFile): Boolean + fun findScriptsWithUsages(declaration: KtNamedDeclaration, processor: (KtFile) -> Boolean): Boolean fun getDefaultImports(file: KtFile): List diff --git a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/searchUtil.kt b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/searchUtil.kt index 65ca4638e04e..56d299403a23 100644 --- a/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/searchUtil.kt +++ b/plugins/kotlin/base/analysis/src/org/jetbrains/kotlin/idea/search/searchUtil.kt @@ -3,29 +3,21 @@ package org.jetbrains.kotlin.idea.search import com.intellij.openapi.project.Project -import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile -import com.intellij.psi.PsiManager import com.intellij.psi.PsiReference -import com.intellij.psi.impl.cache.impl.id.IdIndex -import com.intellij.psi.impl.cache.impl.id.IdIndexEntry import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.LocalSearchScope import com.intellij.psi.search.PsiSearchHelper import com.intellij.psi.search.SearchScope import com.intellij.psi.search.searches.ReferencesSearch -import com.intellij.util.Processor -import com.intellij.util.indexing.FileBasedIndex import org.jetbrains.kotlin.idea.base.util.codeUsageScope import org.jetbrains.kotlin.idea.base.util.projectScope import org.jetbrains.kotlin.idea.base.util.restrictToKotlinSources import org.jetbrains.kotlin.idea.base.util.useScope -import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.scriptDefinitionExists import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtImportDirective -import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.types.expressions.OperatorConventions @@ -105,24 +97,6 @@ fun PsiSearchHelper.isCheapEnoughToSearchConsideringOperators( return isCheapEnoughToSearch(name, scope, fileToIgnoreOccurrencesIn) } -fun findScriptsWithUsages(declaration: KtNamedDeclaration, processor: (KtFile) -> Boolean): Boolean { - val project = declaration.project - val scope = declaration.useScope() as? GlobalSearchScope ?: return true - - val name = declaration.name.takeIf { it?.isNotBlank() == true } ?: return true - val collector = Processor { file -> - val ktFile = - (PsiManager.getInstance(project).findFile(file) as? KtFile)?.takeIf { it.scriptDefinitionExists() } ?: return@Processor true - processor(ktFile) - } - return FileBasedIndex.getInstance().getFilesWithKey( - IdIndex.NAME, - setOf(IdIndexEntry(name, true)), - collector, - scope - ) -} - fun PsiReference.isImportUsage(): Boolean = element.getNonStrictParentOfType() != null diff --git a/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/K2UnusedSymbolUtil.kt b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/K2UnusedSymbolUtil.kt index 8d6b639f0e5c..1904d4315280 100644 --- a/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/K2UnusedSymbolUtil.kt +++ b/plugins/kotlin/highlighting/highlighting-k2/src/org/jetbrains/kotlin/idea/highlighting/K2UnusedSymbolUtil.kt @@ -42,7 +42,7 @@ import org.jetbrains.kotlin.idea.base.util.projectScope import org.jetbrains.kotlin.idea.codeinsight.utils.* import org.jetbrains.kotlin.idea.core.script.configuration.DefaultScriptingSupport import org.jetbrains.kotlin.idea.references.mainReference -import org.jetbrains.kotlin.idea.search.findScriptsWithUsages +import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters import org.jetbrains.kotlin.idea.search.isCheapEnoughToSearchConsideringOperators @@ -193,7 +193,7 @@ object K2UnusedSymbolUtil { val project = declaration.project val psiSearchHelper = PsiSearchHelper.getInstance(project) - if (!findScriptsWithUsages(declaration) { DefaultScriptingSupport.getInstance(project).isLoadedFromCache(it) }) { + if (!KotlinSearchUsagesSupport.getInstance(project).findScriptsWithUsages(declaration) { DefaultScriptingSupport.getInstance(project).isLoadedFromCache(it) }) { // Not all script configurations are loaded; behave like it is used return PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES } diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt index 77b36dd4f024..1b339067be1d 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt @@ -70,7 +70,7 @@ import org.jetbrains.kotlin.idea.isMainFunction import org.jetbrains.kotlin.idea.quickfix.RemoveUnusedFunctionParameterFix import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors -import org.jetbrains.kotlin.idea.search.findScriptsWithUsages +import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters import org.jetbrains.kotlin.idea.search.isCheapEnoughToSearchConsideringOperators @@ -150,7 +150,9 @@ class UnusedSymbolInspection : AbstractKotlinInspection() { val project = declaration.project val psiSearchHelper = PsiSearchHelper.getInstance(project) - if (!findScriptsWithUsages(declaration) { DefaultScriptingSupport.getInstance(project).isLoadedFromCache(it) } && !ApplicationManager.getApplication().isUnitTestMode) { + if (!KotlinSearchUsagesSupport.getInstance(project).findScriptsWithUsages(declaration) { + DefaultScriptingSupport.getInstance(project).isLoadedFromCache(it) } + && !ApplicationManager.getApplication().isUnitTestMode) { // Not all script configuration are loaded; behave like it is used return TOO_MANY_OCCURRENCES } diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/search/KotlinSearchUsagesSupportImpl.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/search/KotlinSearchUsagesSupportImpl.kt index 4ff87923b89a..d7a3d128730d 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/search/KotlinSearchUsagesSupportImpl.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/search/KotlinSearchUsagesSupportImpl.kt @@ -3,18 +3,28 @@ package org.jetbrains.kotlin.idea.search +import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.* +import com.intellij.psi.impl.cache.impl.id.IdIndex +import com.intellij.psi.impl.cache.impl.id.IdIndexEntry +import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.SearchScope +import com.intellij.util.Processor +import com.intellij.util.indexing.FileBasedIndex import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.idea.base.plugin.useK2Plugin +import org.jetbrains.kotlin.idea.base.util.useScope import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.util.hasJavaResolutionFacade import org.jetbrains.kotlin.idea.core.getDirectlyOverriddenDeclarations import org.jetbrains.kotlin.idea.core.isInheritable import org.jetbrains.kotlin.idea.core.isOverridable +import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.SearchUtils.scriptDefinitionExists import org.jetbrains.kotlin.idea.search.usagesSearch.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.ImportPath +import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition class KotlinSearchUsagesSupportImpl : KotlinSearchUsagesSupport { override fun isInvokeOfCompanionObject(psiReference: PsiReference, searchTarget: KtNamedDeclaration): Boolean { @@ -57,7 +67,25 @@ class KotlinSearchUsagesSupportImpl : KotlinSearchUsagesSupport { file.forceResolveReferences(elements) override fun scriptDefinitionExists(file: PsiFile): Boolean = - file.scriptDefinitionExists() + file.findScriptDefinition() != null + + override fun findScriptsWithUsages(declaration: KtNamedDeclaration, processor: (KtFile) -> Boolean): Boolean { + val project = declaration.project + val scope = declaration.useScope() as? GlobalSearchScope ?: return true + + val name = declaration.name.takeIf { it?.isNotBlank() == true } ?: return true + val collector = Processor { file -> + val ktFile = + (PsiManager.getInstance(project).findFile(file) as? KtFile)?.takeIf { it.scriptDefinitionExists() } ?: return@Processor true + processor(ktFile) + } + return FileBasedIndex.getInstance().getFilesWithKey( + IdIndex.NAME, + setOf(IdIndexEntry(name, true)), + collector, + scope + ) + } override fun getDefaultImports(file: KtFile): List = file.getDefaultImports() diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt index 59f20c9a6bec..705da8ba44c2 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt @@ -277,4 +277,3 @@ fun KtFile.getDefaultImports(): List { .getDefaultImports(languageVersionSettings, includeLowPriorityImports = true) } -fun PsiFile.scriptDefinitionExists(): Boolean = findScriptDefinition() != null diff --git a/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2SearchUsagesSupport.kt b/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2SearchUsagesSupport.kt index 8824895c01e8..69da3c6e35c4 100644 --- a/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2SearchUsagesSupport.kt +++ b/plugins/kotlin/kotlin.searching/src/org/jetbrains/kotlin/idea/searching/usages/KotlinK2SearchUsagesSupport.kt @@ -270,6 +270,10 @@ internal class KotlinK2SearchUsagesSupport : KotlinSearchUsagesSupport { return false } + override fun findScriptsWithUsages(declaration: KtNamedDeclaration, processor: (KtFile) -> Boolean): Boolean { + return true + } + override fun getDefaultImports(file: KtFile): List { return file.getDefaultImports() }