mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 06:50:54 +07:00
[kotlin] KTIJ-25208, KTIJ-31165 type safe processing util methods
GitOrigin-RevId: 4c9f1209f7e4fbd7d7b0d91fdb868adb33a673b5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1b2256358c
commit
a082ee2095
@@ -99,10 +99,8 @@ private class IdeKotlinDeclarationProvider(
|
||||
classId.asStringForIndexes(),
|
||||
project,
|
||||
scope
|
||||
) {
|
||||
ProgressManager.checkCanceled()
|
||||
it.getClassId() == classId
|
||||
}
|
||||
) { it.getClassId() == classId }
|
||||
.toList()
|
||||
|
||||
override fun getAllTypeAliasesByClassId(classId: ClassId): Collection<KtTypeAlias> {
|
||||
return listOfNotNull(getTypeAliasByClassId(classId)) //todo
|
||||
|
||||
@@ -9,26 +9,19 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMember
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.PsiShortNamesCache
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.analysis.api.KaExperimentalApi
|
||||
import org.jetbrains.kotlin.analysis.api.KaSession
|
||||
import org.jetbrains.kotlin.analysis.api.analyze
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaClassType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaFlexibleType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaIntersectionType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaTypeNullability
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaTypeParameterType
|
||||
import org.jetbrains.kotlin.analysis.api.types.*
|
||||
import org.jetbrains.kotlin.base.analysis.isExcludedFromAutoImport
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExpectDeclaration
|
||||
import org.jetbrains.kotlin.idea.base.psi.kotlinFqName
|
||||
import org.jetbrains.kotlin.idea.stubindex.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExpectDeclaration
|
||||
import org.jetbrains.kotlin.serialization.deserialization.METADATA_FILE_EXTENSION
|
||||
import org.jetbrains.kotlin.utils.yieldIfNotNull
|
||||
|
||||
@OptIn(KaExperimentalApi::class)
|
||||
class KtSymbolFromIndexProvider private constructor(
|
||||
@@ -39,11 +32,14 @@ class KtSymbolFromIndexProvider private constructor(
|
||||
get() = useSiteFile.project
|
||||
|
||||
context(KaSession)
|
||||
private fun useSiteFilter(element: PsiElement): Boolean {
|
||||
if (element.kotlinFqName?.isExcludedFromAutoImport(project, useSiteFile) == true) return false
|
||||
private fun <T : PsiElement> T.isAcceptable(psiFilter: (T) -> Boolean): Boolean {
|
||||
if (!psiFilter(this)) return false
|
||||
|
||||
val isCommon = useSiteModule.targetPlatform.isCommon()
|
||||
return isCommon || (element as? KtDeclaration)?.isExpectDeclaration() != true
|
||||
if (kotlinFqName?.isExcludedFromAutoImport(project, useSiteFile) == true) return false
|
||||
|
||||
return this !is KtDeclaration
|
||||
|| !isExpectDeclaration()
|
||||
|| useSiteModule.targetPlatform.isCommon()
|
||||
}
|
||||
|
||||
context(KaSession)
|
||||
@@ -51,12 +47,15 @@ class KtSymbolFromIndexProvider private constructor(
|
||||
name: Name,
|
||||
psiFilter: (KtClassLikeDeclaration) -> Boolean = { true },
|
||||
): Sequence<KaClassLikeSymbol> {
|
||||
val valueFilter: (KtClassLikeDeclaration) -> Boolean = { psiFilter(it) && useSiteFilter(it) }
|
||||
val resolveExtensionScope = resolveExtensionScopeWithTopLevelDeclarations
|
||||
|
||||
return getClassLikeSymbols(
|
||||
classDeclarations = KotlinClassShortNameIndex.getAllElements(name.asString(), project, scope, valueFilter),
|
||||
typeAliasDeclarations = KotlinTypeAliasShortNameIndex.getAllElements(name.asString(), project, scope, valueFilter),
|
||||
classDeclarations = KotlinClassShortNameIndex.getAllElements(name.asString(), project, scope) {
|
||||
it.isAcceptable(psiFilter)
|
||||
},
|
||||
typeAliasDeclarations = KotlinTypeAliasShortNameIndex.getAllElements(name.asString(), project, scope) {
|
||||
it.isAcceptable(psiFilter)
|
||||
},
|
||||
declarationsFromExtension = resolveExtensionScope.classifiers(name).filterIsInstance<KaClassLikeSymbol>(),
|
||||
)
|
||||
}
|
||||
@@ -67,30 +66,28 @@ class KtSymbolFromIndexProvider private constructor(
|
||||
psiFilter: (KtClassLikeDeclaration) -> Boolean = { true },
|
||||
): Sequence<KaClassLikeSymbol> {
|
||||
val keyFilter: (String) -> Boolean = { nameFilter(getShortName(it)) }
|
||||
val valueFilter: (KtClassLikeDeclaration) -> Boolean = { psiFilter(it) && useSiteFilter(it) }
|
||||
val resolveExtensionScope = resolveExtensionScopeWithTopLevelDeclarations
|
||||
|
||||
return getClassLikeSymbols(
|
||||
classDeclarations = KotlinFullClassNameIndex.getAllElements(project, scope, keyFilter, valueFilter),
|
||||
typeAliasDeclarations = KotlinTypeAliasShortNameIndex.getAllElements(project, scope, keyFilter, valueFilter),
|
||||
classDeclarations = KotlinFullClassNameIndex.getAllElements(project, scope, keyFilter) {
|
||||
it.isAcceptable(psiFilter)
|
||||
},
|
||||
typeAliasDeclarations = KotlinTypeAliasShortNameIndex.getAllElements(project, scope, keyFilter) {
|
||||
it.isAcceptable(psiFilter)
|
||||
},
|
||||
declarationsFromExtension = resolveExtensionScope.classifiers(nameFilter).filterIsInstance<KaClassLikeSymbol>(),
|
||||
)
|
||||
}
|
||||
|
||||
context(KaSession)
|
||||
private fun getClassLikeSymbols(
|
||||
classDeclarations: List<KtClassOrObject>,
|
||||
typeAliasDeclarations: List<KtTypeAlias>,
|
||||
classDeclarations: Sequence<KtClassOrObject>,
|
||||
typeAliasDeclarations: Sequence<KtTypeAlias>,
|
||||
declarationsFromExtension: Sequence<KaClassLikeSymbol>
|
||||
): Sequence<KaClassLikeSymbol> = sequence {
|
||||
for (ktClassOrObject in classDeclarations) {
|
||||
yieldIfNotNull(ktClassOrObject.namedClassSymbol)
|
||||
}
|
||||
for (typeAlias in typeAliasDeclarations) {
|
||||
yield(typeAlias.symbol)
|
||||
}
|
||||
yieldAll(declarationsFromExtension)
|
||||
}
|
||||
): Sequence<KaClassLikeSymbol> =
|
||||
classDeclarations.mapNotNull { it.namedClassSymbol } +
|
||||
typeAliasDeclarations.map { it.symbol } +
|
||||
declarationsFromExtension
|
||||
|
||||
context(KaSession)
|
||||
fun getJavaClassesByNameFilter(
|
||||
@@ -127,7 +124,7 @@ class KtSymbolFromIndexProvider private constructor(
|
||||
|
||||
return nonKotlinNamesCaches.flatMap { cache ->
|
||||
cache.getClassesByName(nameString, scope).asSequence()
|
||||
}.filter { psiFilter(it) && useSiteFilter(it) }
|
||||
}.filter { it.isAcceptable(psiFilter) }
|
||||
.mapNotNull { it.namedClassSymbol }
|
||||
}
|
||||
|
||||
@@ -135,25 +132,27 @@ class KtSymbolFromIndexProvider private constructor(
|
||||
fun getKotlinCallableSymbolsByName(
|
||||
name: Name,
|
||||
psiFilter: (KtCallableDeclaration) -> Boolean = { true },
|
||||
): Sequence<KaCallableSymbol> {
|
||||
val nameString = name.asString()
|
||||
|
||||
val values = SmartList<KtNamedDeclaration>()
|
||||
val processor = CancelableCollectFilterProcessor(values) {
|
||||
it is KtCallableDeclaration && psiFilter(it) && useSiteFilter(it) && !it.isKotlinBuiltins()
|
||||
): Sequence<KaCallableSymbol> = sequenceOf(
|
||||
KotlinFunctionShortNameIndex,
|
||||
KotlinPropertyShortNameIndex,
|
||||
).flatMap { helper ->
|
||||
val processor = CancelableCollectFilterProcessor { declaration: KtNamedDeclaration ->
|
||||
declaration is KtCallableDeclaration
|
||||
&& declaration.isAcceptable(psiFilter)
|
||||
&& !declaration.isKotlinBuiltins()
|
||||
}
|
||||
KotlinFunctionShortNameIndex.processElements(nameString, project, scope, processor)
|
||||
KotlinPropertyShortNameIndex.processElements(nameString, project, scope, processor)
|
||||
|
||||
return sequence {
|
||||
for (callableDeclaration in values) {
|
||||
yieldIfNotNull(callableDeclaration.symbol as? KaCallableSymbol)
|
||||
}
|
||||
yieldAll(
|
||||
resolveExtensionScopeWithTopLevelDeclarations.callables(name)
|
||||
)
|
||||
}
|
||||
}
|
||||
helper.processElements(
|
||||
key = name.asString(),
|
||||
project = project,
|
||||
scope = scope,
|
||||
processor = processor,
|
||||
)
|
||||
|
||||
processor.results
|
||||
}.map { it.symbol }
|
||||
.filterIsInstance<KaCallableSymbol>() +
|
||||
resolveExtensionScopeWithTopLevelDeclarations.callables(name)
|
||||
|
||||
context(KaSession)
|
||||
fun getJavaCallableSymbolsByName(
|
||||
@@ -165,7 +164,7 @@ class KtSymbolFromIndexProvider private constructor(
|
||||
return nonKotlinNamesCaches.flatMap { cache ->
|
||||
cache.getMethodsByName(nameString, scope).asSequence() +
|
||||
cache.getFieldsByName(nameString, scope)
|
||||
}.filter { psiFilter(it) && useSiteFilter(it) }
|
||||
}.filter { it.isAcceptable(psiFilter) }
|
||||
.mapNotNull { it.callableSymbol }
|
||||
}
|
||||
|
||||
@@ -176,25 +175,28 @@ class KtSymbolFromIndexProvider private constructor(
|
||||
fun getTopLevelCallableSymbolsByNameFilter(
|
||||
nameFilter: (Name) -> Boolean,
|
||||
psiFilter: (KtCallableDeclaration) -> Boolean = { true }
|
||||
): Sequence<KaCallableSymbol> {
|
||||
val values = SmartList<KtCallableDeclaration>()
|
||||
val processor = CancelableCollectFilterProcessor(values) {
|
||||
psiFilter(it) && useSiteFilter(it) && !it.isKotlinBuiltins() && it.receiverTypeReference == null
|
||||
): Sequence<KaCallableSymbol> = sequenceOf(
|
||||
KotlinTopLevelFunctionFqnNameIndex,
|
||||
KotlinTopLevelPropertyFqnNameIndex,
|
||||
).flatMap { helper ->
|
||||
val processor = CancelableCollectFilterProcessor { declaration: KtCallableDeclaration ->
|
||||
declaration.isAcceptable(psiFilter)
|
||||
&& !declaration.isKotlinBuiltins()
|
||||
&& declaration.receiverTypeReference == null
|
||||
}
|
||||
|
||||
val keyFilter: (String) -> Boolean = { nameFilter(getShortName(it)) }
|
||||
KotlinTopLevelFunctionFqnNameIndex.processAllElements(project, scope, keyFilter, processor)
|
||||
KotlinTopLevelPropertyFqnNameIndex.processAllElements(project, scope, keyFilter, processor)
|
||||
helper.processAllElements(
|
||||
project = project,
|
||||
scope = scope,
|
||||
filter = { nameFilter(getShortName(it)) },
|
||||
processor = processor,
|
||||
)
|
||||
|
||||
return sequence {
|
||||
for (callableDeclaration in values) {
|
||||
yieldIfNotNull(callableDeclaration.symbol as? KaCallableSymbol)
|
||||
}
|
||||
yieldAll(
|
||||
resolveExtensionScopeWithTopLevelDeclarations.callables(nameFilter).filter { !it.isExtension }
|
||||
)
|
||||
}
|
||||
}
|
||||
processor.results
|
||||
}.map { it.symbol }
|
||||
.filterIsInstance<KaCallableSymbol>() +
|
||||
resolveExtensionScopeWithTopLevelDeclarations.callables(nameFilter)
|
||||
.filterNot { it.isExtension }
|
||||
|
||||
context(KaSession)
|
||||
fun getExtensionCallableSymbolsByName(
|
||||
@@ -213,10 +215,9 @@ class KtSymbolFromIndexProvider private constructor(
|
||||
).flatMap { indexHelper ->
|
||||
val key = KotlinExtensionsByReceiverTypeStubIndexHelper.Companion.Key(receiverTypeName, name)
|
||||
|
||||
indexHelper.getAllElements(key.key, project, scope) {
|
||||
psiFilter(it)
|
||||
&& useSiteFilter(it)
|
||||
&& !it.isKotlinBuiltins()
|
||||
indexHelper.getAllElements(key.key, project, scope) { declaration ->
|
||||
declaration.isAcceptable(psiFilter)
|
||||
&& !declaration.isKotlinBuiltins()
|
||||
}
|
||||
}
|
||||
}.map { it.symbol }
|
||||
@@ -247,10 +248,9 @@ class KtSymbolFromIndexProvider private constructor(
|
||||
KotlinTopLevelExtensionsByReceiverTypeIndex,
|
||||
KotlinExtensionsInObjectsByReceiverTypeIndex,
|
||||
).flatMap { index ->
|
||||
index.getAllElements(project, scope, keyFilter) {
|
||||
psiFilter(it)
|
||||
&& useSiteFilter(it)
|
||||
&& !it.isKotlinBuiltins()
|
||||
index.getAllElements(project, scope, keyFilter) { declaration: KtCallableDeclaration ->
|
||||
declaration.isAcceptable(psiFilter)
|
||||
&& !declaration.isKotlinBuiltins()
|
||||
}
|
||||
}.map { it.symbol }
|
||||
.filterIsInstance<KaCallableSymbol>()
|
||||
@@ -340,8 +340,12 @@ class KtSymbolFromIndexProvider private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private val KotlinBuiltins = setOf("kotlin/ArrayIntrinsicsKt", "kotlin/internal/ProgressionUtilKt")
|
||||
fun KtCallableDeclaration.isKotlinBuiltins(): Boolean {
|
||||
private val KotlinBuiltins = setOf(
|
||||
"kotlin/ArrayIntrinsicsKt",
|
||||
"kotlin/internal/ProgressionUtilKt",
|
||||
)
|
||||
|
||||
private fun KtCallableDeclaration.isKotlinBuiltins(): Boolean {
|
||||
val file = containingKtFile
|
||||
val virtualFile = file.virtualFile
|
||||
if (virtualFile.extension == METADATA_FILE_EXTENSION) return true
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.api.projectStructure.KaModule
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExpectDeclaration
|
||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelExpectFunctionFqNameIndex
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelExpectPropertyFqNameIndex
|
||||
@@ -15,6 +14,7 @@ import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExpectDeclaration
|
||||
|
||||
object ExpectActualUtils {
|
||||
fun KtDeclaration.expectedDeclarationIfAny(): KtDeclaration? =
|
||||
@@ -50,20 +50,12 @@ object ExpectActualUtils {
|
||||
} ?: unwrappedElement
|
||||
|
||||
fun collectTopLevelExpectDeclarations(project: Project, modules: List<KaModule>): List<KtNamedDeclaration> {
|
||||
val searchScope = GlobalSearchScope.union(modules.map { module -> module.contentScope })
|
||||
val searchScope = GlobalSearchScope.union(modules.map { it.contentScope })
|
||||
|
||||
val indexes = listOf(
|
||||
return sequenceOf(
|
||||
KotlinTopLevelExpectFunctionFqNameIndex,
|
||||
KotlinTopLevelExpectPropertyFqNameIndex,
|
||||
)
|
||||
|
||||
return indexes.flatMap { index ->
|
||||
index.getAllElements(
|
||||
project,
|
||||
searchScope,
|
||||
keyFilter = { true },
|
||||
valueFilter = { true }
|
||||
)
|
||||
}
|
||||
).flatMap { it.getAllElements<KtNamedDeclaration>(project, searchScope) }
|
||||
.toList()
|
||||
}
|
||||
}
|
||||
@@ -106,25 +106,23 @@ class KotlinIndicesHelper(
|
||||
fun getTopLevelExtensionOperatorsByName(name: String): Collection<FunctionDescriptor> {
|
||||
return KotlinFunctionShortNameIndex.getAllElements(name, project, scope) {
|
||||
it.parent is KtFile && it.receiverTypeReference != null && it.hasModifier(KtTokens.OPERATOR_KEYWORD)
|
||||
}
|
||||
.flatMap {
|
||||
ProgressManager.checkCanceled()
|
||||
it.resolveToDescriptors<FunctionDescriptor>()
|
||||
}
|
||||
.filter { descriptorFilter(it) && it.extensionReceiverParameter != null }
|
||||
.distinct()
|
||||
}.flatMap {
|
||||
ProgressManager.checkCanceled()
|
||||
it.resolveToDescriptors<FunctionDescriptor>()
|
||||
}.filter { descriptorFilter(it) }
|
||||
.filter { it.extensionReceiverParameter != null }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
fun getMemberOperatorsByName(name: String): Collection<FunctionDescriptor> {
|
||||
return KotlinFunctionShortNameIndex.getAllElements(name, project, scope) {
|
||||
it.parent is KtClassBody && it.receiverTypeReference == null && it.hasModifier(KtTokens.OPERATOR_KEYWORD)
|
||||
}
|
||||
.flatMap {
|
||||
ProgressManager.checkCanceled()
|
||||
it.resolveToDescriptors<FunctionDescriptor>()
|
||||
}
|
||||
.filter { descriptorFilter(it) && it.extensionReceiverParameter == null }
|
||||
.distinct()
|
||||
}.flatMap {
|
||||
ProgressManager.checkCanceled()
|
||||
it.resolveToDescriptors<FunctionDescriptor>()
|
||||
}.filter { descriptorFilter(it) }
|
||||
.filter { it.extensionReceiverParameter == null }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
fun processTopLevelCallables(nameFilter: (String) -> Boolean, processor: (CallableDescriptor) -> Unit) {
|
||||
@@ -317,7 +315,8 @@ class KotlinIndicesHelper(
|
||||
fun getKotlinEnumsByName(name: String): Collection<DeclarationDescriptor> {
|
||||
val enumEntries = KotlinClassShortNameIndex.getAllElements(name, project, scope) {
|
||||
it is KtEnumEntry
|
||||
}
|
||||
}.toList()
|
||||
|
||||
val result = HashSet<DeclarationDescriptor>(enumEntries.size)
|
||||
for (enumEntry in enumEntries) {
|
||||
ProgressManager.checkCanceled()
|
||||
|
||||
@@ -12,9 +12,9 @@ import com.intellij.psi.stubs.StubIndexKey
|
||||
import com.intellij.util.CommonProcessors
|
||||
import com.intellij.util.Processor
|
||||
import com.intellij.util.Processors
|
||||
import com.intellij.util.SmartList
|
||||
import com.intellij.util.indexing.IdFilter
|
||||
import org.jetbrains.kotlin.idea.base.indices.*
|
||||
import org.jetbrains.kotlin.idea.base.indices.getAllKeysAndMeasure
|
||||
import org.jetbrains.kotlin.idea.base.indices.getByKeyAndMeasure
|
||||
import org.jetbrains.kotlin.idea.base.indices.processAllKeysAndMeasure
|
||||
import org.jetbrains.kotlin.idea.base.indices.processElementsAndMeasure
|
||||
|
||||
@@ -32,10 +32,15 @@ abstract class KotlinStringStubIndexHelper<Key : NavigatablePsiElement>(private
|
||||
return getAllKeysAndMeasure(indexKey, logger) { StubIndex.getInstance().getAllKeys(indexKey, project) }
|
||||
}
|
||||
|
||||
fun getAllElements(s: String, project: Project, scope: GlobalSearchScope, filter: (Key) -> Boolean): List<Key> {
|
||||
val values = SmartList<Key>()
|
||||
processElements(s, project, scope, null, CancelableCollectFilterProcessor(values, filter))
|
||||
return values
|
||||
fun getAllElements(
|
||||
key: String,
|
||||
project: Project,
|
||||
scope: GlobalSearchScope,
|
||||
filter: (Key) -> Boolean = { true },
|
||||
): Sequence<Key> {
|
||||
val processor = CancelableCollectFilterProcessor<Key>(filter = filter)
|
||||
processElements(key, project, scope, null, processor)
|
||||
return processor.results.asSequence() // todo move valueFilter out
|
||||
}
|
||||
/**
|
||||
* Note: [processor] should not invoke any indices as it could lead to deadlock. Nested index access is forbidden.
|
||||
@@ -47,21 +52,30 @@ abstract class KotlinStringStubIndexHelper<Key : NavigatablePsiElement>(private
|
||||
/**
|
||||
* Note: [processor] should not invoke any indices as it could lead to deadlock. Nested index access is forbidden.
|
||||
*/
|
||||
fun processElements(s: String, project: Project, scope: GlobalSearchScope, idFilter: IdFilter? = null, processor: Processor<in Key>): Boolean {
|
||||
return processElementsAndMeasure(indexKey, logger) {
|
||||
StubIndex.getInstance().processElements(indexKey, s, project, scope, idFilter, valueClass, processor)
|
||||
}
|
||||
}
|
||||
|
||||
fun getAllElements(
|
||||
fun processElements(
|
||||
key: String,
|
||||
project: Project,
|
||||
scope: GlobalSearchScope,
|
||||
keyFilter: (String) -> Boolean = { true },
|
||||
valueFilter: (Key) -> Boolean
|
||||
): List<Key> {
|
||||
val values = SmartList<Key>()
|
||||
processAllElements(project, scope, keyFilter, CancelableCollectFilterProcessor(values, valueFilter))
|
||||
return values
|
||||
idFilter: IdFilter? = null,
|
||||
processor: Processor<in Key>,
|
||||
): Boolean = processElementsAndMeasure(indexKey, logger) {
|
||||
StubIndex.getInstance().processElements(indexKey, key, project, scope, idFilter, valueClass, processor)
|
||||
}
|
||||
|
||||
inline fun <reified SubKey> getAllElements(
|
||||
project: Project,
|
||||
scope: GlobalSearchScope,
|
||||
noinline keyFilter: (String) -> Boolean = { true },
|
||||
noinline valueFilter: (SubKey) -> Boolean = { true },
|
||||
): Sequence<SubKey> {
|
||||
val processor = CancelableCollectFilterProcessor<SubKey>(filter = valueFilter)
|
||||
processAllElements(project, scope, keyFilter) { key ->
|
||||
if (key is SubKey)
|
||||
processor.process(key)
|
||||
else
|
||||
true
|
||||
}
|
||||
return processor.results.asSequence() // todo move valueFilter out
|
||||
}
|
||||
|
||||
fun processAllElements(
|
||||
@@ -132,9 +146,10 @@ class CancelableDelegateFilterProcessor<T>(
|
||||
}
|
||||
|
||||
class CancelableCollectFilterProcessor<T>(
|
||||
collection: Collection<T>,
|
||||
private val filter: (T) -> Boolean
|
||||
collection: Collection<T> = mutableListOf(),
|
||||
private val filter: (T) -> Boolean,
|
||||
) : CommonProcessors.CollectProcessor<T>(collection) {
|
||||
|
||||
override fun process(t: T): Boolean {
|
||||
ProgressManager.checkCanceled()
|
||||
return super.process(t)
|
||||
|
||||
@@ -27,13 +27,13 @@ fun KtDeclaration.findAllActualForExpect(searchScope: SearchScope = runReadActio
|
||||
// covers cases like classes, class functions and class properties
|
||||
containingClassOrObjectOrSelf?.fqName?.let { fqName ->
|
||||
val fqNameAsString = fqName.asString()
|
||||
val targetDeclarations: List<KtDeclaration> = KotlinFullClassNameIndex.getAllElements(fqNameAsString, project, scope, filter = {
|
||||
val targetDeclarations = KotlinFullClassNameIndex.getAllElements(fqNameAsString, project, scope) {
|
||||
it.matchesWithExpect(containingClassOrObjectOrSelf)
|
||||
}) + KotlinTopLevelTypeAliasFqNameIndex.getAllElements(fqNameAsString, project, scope, filter = {
|
||||
} + KotlinTopLevelTypeAliasFqNameIndex.getAllElements(fqNameAsString, project, scope) {
|
||||
it.matchesWithExpect(containingClassOrObjectOrSelf)
|
||||
})
|
||||
}
|
||||
|
||||
return targetDeclarations.asSequence().mapNotNull { targetDeclaration ->
|
||||
return targetDeclarations.mapNotNull { targetDeclaration ->
|
||||
when (declaration) {
|
||||
is KtClassOrObject -> targetDeclaration
|
||||
is KtConstructor<*> -> {
|
||||
@@ -56,28 +56,24 @@ fun KtDeclaration.findAllActualForExpect(searchScope: SearchScope = runReadActio
|
||||
}
|
||||
|
||||
else -> null
|
||||
}?.createSmartPointer()
|
||||
}
|
||||
}
|
||||
}.map { it.createSmartPointer() }
|
||||
}
|
||||
// top level functions
|
||||
val packageFqName = declaration.containingKtFile.packageFqName
|
||||
val name = declaration.name ?: return emptySequence()
|
||||
val topLevelFqName = packageFqName.child(Name.identifier(name)).asString()
|
||||
return when (declaration) {
|
||||
is KtNamedFunction -> {
|
||||
KotlinTopLevelFunctionFqnNameIndex.getAllElements(topLevelFqName, project, scope) {
|
||||
it.matchesWithExpect(declaration)
|
||||
}.asSequence().map(KtNamedFunction::createSmartPointer)
|
||||
is KtNamedFunction -> KotlinTopLevelFunctionFqnNameIndex.getAllElements(topLevelFqName, project, scope) {
|
||||
it.matchesWithExpect(declaration)
|
||||
}
|
||||
|
||||
is KtProperty -> {
|
||||
KotlinTopLevelPropertyFqnNameIndex.getAllElements(topLevelFqName, project, scope) {
|
||||
it.matchesWithExpect(declaration)
|
||||
}.asSequence().map(KtProperty::createSmartPointer)
|
||||
is KtProperty -> KotlinTopLevelPropertyFqnNameIndex.getAllElements(topLevelFqName, project, scope) {
|
||||
it.matchesWithExpect(declaration)
|
||||
}
|
||||
|
||||
else -> emptySequence()
|
||||
}
|
||||
}.map { it.createSmartPointer() }
|
||||
}
|
||||
|
||||
@OptIn(KaExperimentalApi::class)
|
||||
|
||||
Reference in New Issue
Block a user