remove old usages search implementation
This commit is contained in:
+1
-1
@@ -88,7 +88,7 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
|
||||
}
|
||||
words.forEach { word ->
|
||||
queryParameters.optimizer.searchWord(word, effectiveSearchScope,
|
||||
UsagesSearchLocation.EVERYWHERE.searchContext, true, unwrappedElement,
|
||||
UsageSearchContext.ANY, true, unwrappedElement,
|
||||
resultProcessor)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,74 +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.search.usagesSearch
|
||||
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchFilter.*
|
||||
|
||||
class OrFilter(val filter1: UsagesSearchFilter, val filter2: UsagesSearchFilter): UsagesSearchFilter {
|
||||
override fun accepts(ref: PsiReference, item: UsagesSearchRequestItem): Boolean =
|
||||
filter1.accepts(ref, item) || filter2.accepts(ref, item)
|
||||
}
|
||||
|
||||
class AndFilter(val filter1: UsagesSearchFilter, val filter2: UsagesSearchFilter): UsagesSearchFilter {
|
||||
override fun accepts(ref: PsiReference, item: UsagesSearchRequestItem): Boolean =
|
||||
filter1.accepts(ref, item) && filter2.accepts(ref, item)
|
||||
}
|
||||
|
||||
class NotFilter(val filter: UsagesSearchFilter): UsagesSearchFilter {
|
||||
override fun accepts(ref: PsiReference, item: UsagesSearchRequestItem): Boolean =
|
||||
!filter.accepts(ref, item)
|
||||
}
|
||||
|
||||
fun UsagesSearchFilter.or(that: UsagesSearchFilter): UsagesSearchFilter = when {
|
||||
this == False -> that
|
||||
that == False -> this
|
||||
this == True, that == True -> True
|
||||
else -> OrFilter(this, that)
|
||||
}
|
||||
|
||||
fun UsagesSearchFilter.and(that: UsagesSearchFilter): UsagesSearchFilter = when {
|
||||
this == True -> that
|
||||
that == True -> this
|
||||
this == False, that == False -> False
|
||||
else -> AndFilter(this, that)
|
||||
}
|
||||
|
||||
fun UsagesSearchFilter.not(): UsagesSearchFilter = when {
|
||||
this == False -> True
|
||||
this == True -> False
|
||||
else -> NotFilter(this)
|
||||
}
|
||||
|
||||
fun UsagesSearchFilter.ifElse(condition: Boolean, elseFilter: UsagesSearchFilter): UsagesSearchFilter =
|
||||
if (condition) this else elseFilter
|
||||
|
||||
fun UsagesSearchFilter.ifOrFalse(condition: Boolean): UsagesSearchFilter = ifElse(condition, False)
|
||||
|
||||
fun UsagesSearchFilter.ifOrTrue(condition: Boolean): UsagesSearchFilter = ifElse(condition, True)
|
||||
|
||||
val (PsiReference.() -> Boolean).searchFilter: UsagesSearchFilter
|
||||
get() = object: UsagesSearchFilter {
|
||||
override fun accepts(ref: PsiReference, item: UsagesSearchRequestItem): Boolean = ref.this@searchFilter()
|
||||
}
|
||||
|
||||
val <T: PsiNamedElement> (PsiReference.(T) -> Boolean).searchFilter: UsagesSearchFilter
|
||||
get() = object: UsagesSearchFilter {
|
||||
@suppress("UNCHECKED_CAST")
|
||||
override fun accepts(ref: PsiReference, item: UsagesSearchRequestItem): Boolean = ref.this@searchFilter(item.target.element as T)
|
||||
}
|
||||
-233
@@ -16,40 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.search.usagesSearch
|
||||
|
||||
import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.UsageSearchContext
|
||||
import com.intellij.util.Processor
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil.PropertyAccessorsPsiMethods
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference
|
||||
import org.jetbrains.kotlin.idea.references.matchesTarget
|
||||
import org.jetbrains.kotlin.idea.search.KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT
|
||||
import org.jetbrains.kotlin.idea.search.and
|
||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDetector
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchFilter.False
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchFilter.True
|
||||
import org.jetbrains.kotlin.idea.stubindex.JetSourceFilterScope
|
||||
import org.jetbrains.kotlin.lexer.JetSingleValueToken
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.effectiveDeclarations
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassReceiver
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||
import java.util.*
|
||||
|
||||
val isTargetUsage = (PsiReference::matchesTarget).searchFilter
|
||||
|
||||
fun PsiNamedElement.getAccessorNames(readable: Boolean = true, writable: Boolean = true): List<String> {
|
||||
fun PropertyAccessorsPsiMethods.toNameList(): List<String> {
|
||||
val getter = getGetter()
|
||||
@@ -110,217 +90,4 @@ fun JetParameter.dataClassComponentFunction(): FunctionDescriptor? {
|
||||
return context[BindingContext.DATA_CLASS_COMPONENT_FUNCTION, paramDescriptor]
|
||||
}
|
||||
|
||||
public abstract class UsagesSearchHelper<T : PsiNamedElement> {
|
||||
protected open fun makeFilter(target: UsagesSearchTarget<T>): UsagesSearchFilter = isTargetUsage
|
||||
|
||||
protected open fun makeWordList(target: UsagesSearchTarget<T>): List<String> {
|
||||
return with(target.element) {
|
||||
getName().singletonOrEmptyList() + getAccessorNames() + getClassNameForCompanionObject().singletonOrEmptyList() + getSpecialNamesToSearch()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected open fun makeItemList(target: UsagesSearchTarget<T>): List<UsagesSearchRequestItem> =
|
||||
Collections.singletonList(newItem(target))
|
||||
|
||||
protected open fun makeAdditionalSearchDelegate(target: T): ((Processor<PsiReference>) -> Boolean)? = null
|
||||
|
||||
fun newItem(target: UsagesSearchTarget<T>): UsagesSearchRequestItem {
|
||||
return UsagesSearchRequestItem(target, makeWordList(target), makeFilter(target), makeAdditionalSearchDelegate(target.element))
|
||||
}
|
||||
|
||||
fun newRequest(target: UsagesSearchTarget<T>): UsagesSearchRequest {
|
||||
return UsagesSearchRequest(target.element.getProject(), makeItemList(target))
|
||||
}
|
||||
}
|
||||
|
||||
val isNotImportUsage = !((PsiReference::isImportUsage).searchFilter)
|
||||
|
||||
interface ImportAwareSearchHelper {
|
||||
public val skipImports: Boolean
|
||||
|
||||
protected val isFilteredImport: UsagesSearchFilter
|
||||
get() = isNotImportUsage.ifOrTrue(skipImports)
|
||||
}
|
||||
|
||||
open class DefaultSearchHelper<T: PsiNamedElement>(
|
||||
override val skipImports: Boolean = false
|
||||
): UsagesSearchHelper<T>(), ImportAwareSearchHelper {
|
||||
override fun makeFilter(target: UsagesSearchTarget<T>): UsagesSearchFilter = isTargetUsage and isFilteredImport
|
||||
}
|
||||
|
||||
val isClassConstructorUsage = (PsiReference::isConstructorUsage).searchFilter
|
||||
|
||||
class ClassUsagesSearchHelper(
|
||||
public val constructorUsages: Boolean = false,
|
||||
public val nonConstructorUsages: Boolean = false,
|
||||
skipImports: Boolean = false
|
||||
) : DefaultSearchHelper<JetClassOrObject>(skipImports) {
|
||||
override fun makeFilter(target: UsagesSearchTarget<JetClassOrObject>): UsagesSearchFilter =
|
||||
super.makeFilter(target) and when {
|
||||
constructorUsages && !nonConstructorUsages -> isClassConstructorUsage
|
||||
!constructorUsages && nonConstructorUsages -> !isClassConstructorUsage
|
||||
!constructorUsages && !nonConstructorUsages -> False
|
||||
else -> True
|
||||
}
|
||||
|
||||
override fun makeAdditionalSearchDelegate(target: JetClassOrObject): ((Processor<PsiReference>) -> Boolean)? {
|
||||
if (target is JetObjectDeclaration && target.isCompanion()) {
|
||||
val companionObjectDescriptor = target.descriptor
|
||||
val klass = target.getStrictParentOfType<JetClass>() ?: return null
|
||||
return { processor ->
|
||||
klass.acceptChildren(object : JetVisitorVoid() {
|
||||
override fun visitJetElement(element: JetElement) {
|
||||
if (element == target) return // skip companion object itself
|
||||
element.acceptChildren(this)
|
||||
|
||||
val bindingContext = element.analyze()
|
||||
val call = bindingContext[BindingContext.CALL, element] ?: return
|
||||
val resolvedCall = bindingContext[BindingContext.RESOLVED_CALL, call] ?: return
|
||||
if ((resolvedCall.getDispatchReceiver() as? ClassReceiver)?.getDeclarationDescriptor() == companionObjectDescriptor
|
||||
|| (resolvedCall.getExtensionReceiver() as? ClassReceiver)?.getDeclarationDescriptor() == companionObjectDescriptor) {
|
||||
element.getReferences().forEach { processor.process(it) }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class ClassDeclarationsUsagesSearchHelper(
|
||||
public val functionUsages: Boolean = false,
|
||||
public val propertyUsages: Boolean = false,
|
||||
skipImports: Boolean = false
|
||||
) : DefaultSearchHelper<JetClassOrObject>(skipImports) {
|
||||
override fun makeItemList(target: UsagesSearchTarget<JetClassOrObject>): List<UsagesSearchRequestItem> {
|
||||
val items = ArrayList<UsagesSearchRequestItem>()
|
||||
val declHelper = DefaultSearchHelper<JetNamedDeclaration>(skipImports)
|
||||
|
||||
for (decl in target.element.effectiveDeclarations()) {
|
||||
if ((decl is JetNamedFunction && functionUsages) || ((decl is JetProperty || decl is JetParameter) && propertyUsages)) {
|
||||
items.add(declHelper.newItem(target.withTarget(decl as JetNamedDeclaration)))
|
||||
}
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
}
|
||||
|
||||
val isOverrideUsage = (PsiReference::isCallableOverrideUsage).searchFilter
|
||||
|
||||
interface OverrideSearchHelper {
|
||||
public val selfUsages: Boolean
|
||||
public val overrideUsages: Boolean
|
||||
|
||||
val isTargetOrOverrideUsage: UsagesSearchFilter
|
||||
get() = isTargetUsage.ifOrFalse(selfUsages) or isOverrideUsage.ifOrFalse(overrideUsages)
|
||||
}
|
||||
|
||||
val isOverloadUsage = (PsiReference::isUsageInContainingDeclaration).searchFilter
|
||||
val isExtensionUsage = (PsiReference::isExtensionOfDeclarationClassUsage).searchFilter
|
||||
|
||||
class FunctionUsagesSearchHelper(
|
||||
public val overloadUsages: Boolean = false,
|
||||
public val extensionUsages: Boolean = false,
|
||||
override val selfUsages: Boolean = true,
|
||||
override val overrideUsages: Boolean = true,
|
||||
skipImports: Boolean = false
|
||||
) : DefaultSearchHelper<JetFunction>(skipImports), OverrideSearchHelper {
|
||||
override fun makeFilter(target: UsagesSearchTarget<JetFunction>): UsagesSearchFilter {
|
||||
return (isTargetOrOverrideUsage
|
||||
or isOverloadUsage.ifOrFalse(overloadUsages)
|
||||
or isExtensionUsage.ifOrFalse(extensionUsages)) and isFilteredImport
|
||||
}
|
||||
}
|
||||
|
||||
// Used for JetProperty and JetParameter
|
||||
class PropertyUsagesSearchHelper(
|
||||
public val readUsages: Boolean = true,
|
||||
public val writeUsages: Boolean = true,
|
||||
public val namedArgumentUsages: Boolean = true,
|
||||
public override val selfUsages: Boolean = true,
|
||||
public override val overrideUsages: Boolean = true,
|
||||
skipImports: Boolean = false
|
||||
) : DefaultSearchHelper<JetNamedDeclaration>(skipImports), OverrideSearchHelper {
|
||||
override fun makeItemList(target: UsagesSearchTarget<JetNamedDeclaration>): List<UsagesSearchRequestItem> {
|
||||
val element = target.element
|
||||
if (element is JetParameter) {
|
||||
val parameterName = element.name ?: return emptyList()
|
||||
|
||||
val realUsagesScope = element.useScope and target.effectiveScope
|
||||
val realUsagesTarget = target.withScope(realUsagesScope)
|
||||
val realUsagesFilter = makeFilter(target) and !(PsiReference::isNamedArgumentUsage).searchFilter
|
||||
val realUsagesRequest = UsagesSearchRequestItem(realUsagesTarget, makeWordList(target), realUsagesFilter, makeAdditionalSearchDelegate(target.element))
|
||||
|
||||
if (!namedArgumentUsages) {
|
||||
return listOf(realUsagesRequest)
|
||||
}
|
||||
|
||||
val function = element.ownerFunction
|
||||
?: return listOf(realUsagesRequest) // parameter in for or something like that
|
||||
if (function.nameAsName?.isSpecial ?: true) { // function literal or anonymous function
|
||||
return listOf(realUsagesRequest)
|
||||
}
|
||||
|
||||
var scope = function.useScope and target.effectiveScope
|
||||
if (scope is GlobalSearchScope) {
|
||||
scope = JetSourceFilterScope.kotlinSourcesAndLibraries(scope, element.project)
|
||||
}
|
||||
|
||||
val additionalFilter1 = AdditionalFileFilter(parameterName, KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT, true)
|
||||
val additionalFilter2 = AdditionalFileFilter(function.name!!, UsageSearchContext.IN_CODE, true)
|
||||
val namedArgsRequest = UsagesSearchRequestItem(target.withScope(scope),
|
||||
listOf(parameterName),
|
||||
(PsiReference::isNamedArgumentUsage).searchFilter and makeFilter(target),
|
||||
additionalFileFilters = listOf(additionalFilter1, additionalFilter2))
|
||||
return listOf(realUsagesRequest, namedArgsRequest)
|
||||
}
|
||||
|
||||
return super<DefaultSearchHelper>.makeItemList(target)
|
||||
}
|
||||
|
||||
override fun makeWordList(target: UsagesSearchTarget<JetNamedDeclaration>): List<String> {
|
||||
return with(target.element) {
|
||||
ContainerUtil.createMaybeSingletonList(getName()) +
|
||||
getAccessorNames(readable = readUsages, writable = writeUsages) +
|
||||
getSpecialNamesToSearch()
|
||||
}
|
||||
}
|
||||
|
||||
override fun makeFilter(target: UsagesSearchTarget<JetNamedDeclaration>): UsagesSearchFilter {
|
||||
val readWriteFilter = object: UsagesSearchFilter {
|
||||
val detector = KotlinReadWriteAccessDetector()
|
||||
|
||||
override fun accepts(ref: PsiReference, item: UsagesSearchRequestItem): Boolean {
|
||||
if (readUsages == writeUsages) return readUsages
|
||||
|
||||
val access = detector.getReferenceAccess(target.element, ref)
|
||||
return when (access) {
|
||||
ReadWriteAccessDetector.Access.Read -> readUsages
|
||||
ReadWriteAccessDetector.Access.Write -> writeUsages
|
||||
ReadWriteAccessDetector.Access.ReadWrite -> true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var result = isTargetOrOverrideUsage and readWriteFilter and isFilteredImport
|
||||
if (!namedArgumentUsages) {
|
||||
result = result and !(PsiReference::isNamedArgumentUsage).searchFilter
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
companion object {
|
||||
}
|
||||
}
|
||||
|
||||
private fun PsiReference.isNamedArgumentUsage(): Boolean {
|
||||
if (this !is JetSimpleNameReference) return false
|
||||
return expression.parent is JetValueArgumentName
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,194 +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.search.usagesSearch
|
||||
|
||||
import com.intellij.openapi.application.QueryExecutorBase
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.FileIndexFacade
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.PsiManagerEx
|
||||
import com.intellij.psi.impl.cache.impl.id.IdIndex
|
||||
import com.intellij.psi.impl.cache.impl.id.IdIndexEntry
|
||||
import com.intellij.psi.impl.search.PsiSearchHelperImpl
|
||||
import com.intellij.psi.search.*
|
||||
import com.intellij.psi.search.searches.ReferenceDescriptor
|
||||
import com.intellij.util.*
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.indexing.FileBasedIndex
|
||||
import org.jetbrains.kotlin.idea.search.and
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchFilter.False
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import java.util.Collections
|
||||
|
||||
public data class UsagesSearchLocation(
|
||||
val inCode: Boolean = true,
|
||||
val inComments: Boolean = false,
|
||||
val inStrings: Boolean = false,
|
||||
val inPlainText: Boolean = true
|
||||
) {
|
||||
companion object {
|
||||
public val DEFAULT: UsagesSearchLocation = UsagesSearchLocation()
|
||||
public val EVERYWHERE: UsagesSearchLocation = UsagesSearchLocation(true, true, true, true)
|
||||
}
|
||||
|
||||
val searchContext: Short
|
||||
get() {
|
||||
var res = 0
|
||||
|
||||
if (inCode) res += UsageSearchContext.IN_CODE + UsageSearchContext.IN_FOREIGN_LANGUAGES
|
||||
if (inComments) res += UsageSearchContext.IN_COMMENTS
|
||||
if (inStrings) res += UsageSearchContext.IN_STRINGS
|
||||
if (inPlainText) res += UsageSearchContext.IN_PLAIN_TEXT
|
||||
|
||||
return res.toShort()
|
||||
}
|
||||
}
|
||||
|
||||
public data class UsagesSearchTarget<out T : PsiElement>(
|
||||
val element: T,
|
||||
private val scope: SearchScope = element.getUseScope(),
|
||||
val location: UsagesSearchLocation = UsagesSearchLocation.DEFAULT,
|
||||
val restrictByTargetScope: Boolean = true
|
||||
) {
|
||||
fun <U: PsiElement> withTarget(element: U) =
|
||||
UsagesSearchTarget(element, scope, location, restrictByTargetScope)
|
||||
|
||||
fun withScope(scope: SearchScope) =
|
||||
UsagesSearchTarget(element, scope, location, restrictByTargetScope)
|
||||
|
||||
val effectiveScope: SearchScope
|
||||
get() = if (restrictByTargetScope) scope and element.effectiveScope else scope
|
||||
}
|
||||
|
||||
public interface UsagesSearchFilter {
|
||||
object False: UsagesSearchFilter {
|
||||
override fun accepts(ref: PsiReference, item: UsagesSearchRequestItem): Boolean = false
|
||||
}
|
||||
|
||||
object True: UsagesSearchFilter {
|
||||
override fun accepts(ref: PsiReference, item: UsagesSearchRequestItem): Boolean = true
|
||||
}
|
||||
|
||||
fun accepts(ref: PsiReference, item: UsagesSearchRequestItem): Boolean
|
||||
}
|
||||
|
||||
public class UsagesSearchRequestItem(
|
||||
val target: UsagesSearchTarget<PsiElement>,
|
||||
val words: List<String>,
|
||||
val filter: UsagesSearchFilter,
|
||||
val additionalSearchDelegate: ((Processor<PsiReference>) -> Boolean)? = null,
|
||||
val additionalFileFilters: Collection<AdditionalFileFilter> = emptyList()
|
||||
)
|
||||
|
||||
public class AdditionalFileFilter(
|
||||
val word: String,
|
||||
val searchContext: Short,
|
||||
val caseSensitively: Boolean
|
||||
)
|
||||
|
||||
public data class UsagesSearchRequest(val project: Project, val items: List<UsagesSearchRequestItem>) {
|
||||
val collector: SearchRequestCollector = SearchRequestCollector(SearchSession())
|
||||
}
|
||||
|
||||
public class KotlinPsiSearchHelper(private val project: Project): PsiSearchHelperImpl(PsiManager.getInstance(project) as PsiManagerEx) {
|
||||
class ResultTextProcessorImpl(
|
||||
private val node: UsagesSearchRequestItem,
|
||||
private val consumer: Processor<PsiReference>
|
||||
): TextOccurenceProcessor {
|
||||
private val referenceService = PsiReferenceService.getService()!!
|
||||
|
||||
override fun execute(element: PsiElement, offsetInElement: Int): Boolean {
|
||||
return referenceService.getReferences(element, PsiReferenceService.Hints.NO_HINTS).all { ref ->
|
||||
ProgressManager.checkCanceled()
|
||||
|
||||
when {
|
||||
!ReferenceRange.containsOffsetInElement(ref, offsetInElement) -> true
|
||||
!node.filter.accepts(ref, node) -> true
|
||||
else -> consumer.process(ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun processFilesWithText(
|
||||
scope: GlobalSearchScope,
|
||||
searchContext: Short,
|
||||
caseSensitively: Boolean,
|
||||
text: String,
|
||||
processor: Processor<VirtualFile>
|
||||
): Boolean {
|
||||
if (text !in ALL_SEARCHABLE_OPERATION_PATTERNS) {
|
||||
return super.processFilesWithText(scope, searchContext, caseSensitively, text, processor)
|
||||
}
|
||||
|
||||
val entries = Collections.singletonList(IdIndexEntry(text, caseSensitively))
|
||||
val index = FileIndexFacade.getInstance(project)
|
||||
val checker: (Int?) -> Boolean = { (it!! and searchContext.toInt()) != 0 }
|
||||
return runReadAction {
|
||||
FileBasedIndex.getInstance().processFilesContainingAllKeys(IdIndex.NAME, entries, scope, checker) { file ->
|
||||
!index.shouldBeFound(scope, file) || processor.process(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun processFilesWithText(item: UsagesSearchRequestItem, consumer: Processor<PsiReference>): Boolean {
|
||||
var scope = runReadAction { item.target.effectiveScope }
|
||||
|
||||
for (filter in item.additionalFileFilters) {
|
||||
if (scope !is GlobalSearchScope) break
|
||||
val processor = CommonProcessors.CollectProcessor<VirtualFile>()
|
||||
processFilesWithText(scope, filter.searchContext, filter.caseSensitively, filter.word, processor)
|
||||
if (processor.results.isEmpty()) return true
|
||||
scope = GlobalSearchScope.filesScope(project, processor.results)
|
||||
}
|
||||
|
||||
return item.words.all { word ->
|
||||
val textProcessor = ResultTextProcessorImpl(item, consumer)
|
||||
processElementsWithWord(textProcessor, scope, word, item.target.location.searchContext, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public object UsagesSearch: QueryFactory<PsiReference, UsagesSearchRequest>() {
|
||||
init {
|
||||
val executorImpl = object : QueryExecutorBase<PsiReference, UsagesSearchRequest>() {
|
||||
override fun processQuery(request: UsagesSearchRequest, consumer: Processor<PsiReference>) {
|
||||
val searchHelper = KotlinPsiSearchHelper(request.project)
|
||||
request.items.filter { it.filter != False }.all {
|
||||
searchHelper.processFilesWithText(it, consumer) && (it.additionalSearchDelegate?.invoke(consumer) ?: true) }
|
||||
}
|
||||
}
|
||||
|
||||
registerExecutor(executorImpl)
|
||||
}
|
||||
|
||||
fun search(request: UsagesSearchRequest): Query<PsiReference> = with(request) {
|
||||
createQuery(this) merge SearchRequestQuery(project, collector).unique
|
||||
}
|
||||
}
|
||||
|
||||
fun UsagesSearchRequest.search(): Query<PsiReference> = UsagesSearch.search(this)
|
||||
|
||||
val PsiElement.effectiveScope: SearchScope
|
||||
get() = PsiSearchHelper.SERVICE.getInstance(getProject())!!.getUseScope(this)
|
||||
|
||||
fun <T> Query<T>.merge(that: Query<T>): Query<T> = MergeQuery(this, that)
|
||||
|
||||
val Query<PsiReference>.unique: Query<PsiReference>
|
||||
get() = UniqueResultsQuery(this, ContainerUtil.canonicalStrategy(), ReferenceDescriptor.MAPPER)
|
||||
@@ -16,14 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.findUsages
|
||||
|
||||
import com.intellij.find.findUsages.FindUsagesOptions
|
||||
import com.intellij.find.findUsages.JavaClassFindUsagesOptions
|
||||
import com.intellij.find.findUsages.JavaMethodFindUsagesOptions
|
||||
import com.intellij.find.findUsages.JavaVariableFindUsagesOptions
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.*
|
||||
|
||||
public class KotlinClassFindUsagesOptions(project: Project) : JavaClassFindUsagesOptions(project) {
|
||||
public var searchConstructorUsages: Boolean = true
|
||||
@@ -81,44 +77,3 @@ public class KotlinPropertyFindUsagesOptions(project: Project): KotlinCallableFi
|
||||
override var searchOverrides: Boolean = false
|
||||
}
|
||||
|
||||
fun KotlinClassFindUsagesOptions.toClassHelper(): ClassUsagesSearchHelper =
|
||||
ClassUsagesSearchHelper(
|
||||
constructorUsages = searchConstructorUsages,
|
||||
nonConstructorUsages = isUsages,
|
||||
skipImports = isSkipImportStatements
|
||||
)
|
||||
|
||||
fun KotlinClassFindUsagesOptions.toClassDeclarationsHelper(): ClassDeclarationsUsagesSearchHelper =
|
||||
ClassDeclarationsUsagesSearchHelper(
|
||||
functionUsages = isMethodsUsages,
|
||||
propertyUsages = isFieldsUsages,
|
||||
skipImports = isSkipImportStatements
|
||||
)
|
||||
|
||||
fun KotlinFunctionFindUsagesOptions.toHelper(): FunctionUsagesSearchHelper =
|
||||
FunctionUsagesSearchHelper(
|
||||
selfUsages = isUsages,
|
||||
overrideUsages = isUsages,
|
||||
overloadUsages = isIncludeOverloadUsages,
|
||||
extensionUsages = isIncludeOverloadUsages,
|
||||
skipImports = isSkipImportStatements
|
||||
)
|
||||
|
||||
fun KotlinPropertyFindUsagesOptions.toHelper(): PropertyUsagesSearchHelper =
|
||||
PropertyUsagesSearchHelper(
|
||||
selfUsages = isUsages,
|
||||
overrideUsages = isUsages,
|
||||
namedArgumentUsages = isUsages,
|
||||
readUsages = isReadAccess,
|
||||
writeUsages = isWriteAccess,
|
||||
skipImports = isSkipImportStatements
|
||||
)
|
||||
|
||||
fun <T : PsiNamedElement> FindUsagesOptions.toSearchTarget(element: T, restrictByTarget: Boolean): UsagesSearchTarget<T> {
|
||||
val location = if (isSearchForTextOccurrences && searchScope is GlobalSearchScope)
|
||||
UsagesSearchLocation.EVERYWHERE
|
||||
else
|
||||
UsagesSearchLocation.DEFAULT
|
||||
|
||||
return UsagesSearchTarget(element, searchScope, location, restrictByTarget)
|
||||
}
|
||||
|
||||
-4
@@ -45,10 +45,6 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.selectElementsWithTargetP
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.showErrorHint
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.showErrorHintByKey
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.DefaultSearchHelper
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchTarget
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.search
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
|
||||
Reference in New Issue
Block a user