diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/scopes/KtFe10FileScope.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/scopes/KtFe10FileScope.kt index 718e13b18f0..a953875c75e 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/scopes/KtFe10FileScope.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/scopes/KtFe10FileScope.kt @@ -8,14 +8,14 @@ package org.jetbrains.kotlin.analysis.api.descriptors.scopes import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtCallableSymbol import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtClassifierSymbol +import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken +import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.scopes.KtScope import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtClassifierSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtPackageSymbol -import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken -import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.name.Name @@ -51,6 +51,12 @@ internal class KtFe10FileScope( } } + override fun getCallableSymbols(names: Collection): Sequence { + if (names.isEmpty()) return emptySequence() + val namesSet = names.toSet() + return getCallableSymbols { it in namesSet } + } + override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { val context = analysisContext.analyze(ktFile) @@ -65,6 +71,12 @@ internal class KtFe10FileScope( } } + override fun getClassifierSymbols(names: Collection): Sequence { + if (names.isEmpty()) return emptySequence() + val namesSet = names.toSet() + return getClassifierSymbols { it in namesSet } + } + override fun getConstructors(): Sequence = withValidityAssertion { emptySequence() } diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/scopes/KtFe10ScopeResolution.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/scopes/KtFe10ScopeResolution.kt index 3546f560e9b..7fe2f517295 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/scopes/KtFe10ScopeResolution.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/scopes/KtFe10ScopeResolution.kt @@ -34,6 +34,12 @@ internal abstract class KtFe10ScopeResolution : KtScope, KtLifetimeOwner { .mapNotNull { it.toKtSymbol(analysisContext) as? KtCallableSymbol } } + override fun getCallableSymbols(names: Collection): Sequence { + if (names.isEmpty()) return emptySequence() + val namesSet = names.toSet() + return getCallableSymbols { it in namesSet } + } + override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { return scope .getContributedDescriptors(kindFilter = DescriptorKindFilter.CLASSIFIERS, nameFilter) @@ -42,6 +48,12 @@ internal abstract class KtFe10ScopeResolution : KtScope, KtLifetimeOwner { .mapNotNull { it.toKtSymbol(analysisContext) as? KtClassifierSymbol } } + override fun getClassifierSymbols(names: Collection): Sequence { + if (names.isEmpty()) return emptySequence() + val namesSet = names.toSet() + return getClassifierSymbols { it in namesSet } + } + override fun getPackageSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { emptySequence() } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolFromResolveExtensionProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolFromResolveExtensionProvider.kt index a1a5845c176..0c9572b65ab 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolFromResolveExtensionProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolFromResolveExtensionProvider.kt @@ -46,10 +46,22 @@ private class KtFirResolveExtensionScope( gelTopLevelDeclarations(nameFilter) { it.getTopLevelCallables() } } + override fun getCallableSymbols(names: Collection): Sequence = withValidityAssertion { + if (names.isEmpty()) return emptySequence() + val namesSet = names.toSet() + return getCallableSymbols { it in namesSet } + } + override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { gelTopLevelDeclarations(nameFilter) { it.getTopLevelClassifiers() } } + override fun getClassifierSymbols(names: Collection): Sequence { + if (names.isEmpty()) return emptySequence() + val namesSet = names.toSet() + return getClassifierSymbols { it in namesSet } + } + private inline fun gelTopLevelDeclarations( crossinline nameFilter: KtScopeNameFilter, crossinline getDeclarationsByProvider: (LLFirResolveExtensionToolDeclarationProvider) -> Sequence, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirDelegatedMemberScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirDelegatedMemberScope.kt index 1492e6cea9e..8cd6085b688 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirDelegatedMemberScope.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirDelegatedMemberScope.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope +import org.jetbrains.kotlin.name.Name internal class KtFirDelegatedMemberScope( firScope: FirContainingNamesAwareScope, @@ -20,4 +21,8 @@ internal class KtFirDelegatedMemberScope( override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { return super.getCallableSymbols(nameFilter).filter { it.origin == KtSymbolOrigin.DELEGATED } } + + override fun getCallableSymbols(names: Collection): Sequence { + return super.getCallableSymbols(names).filter { it.origin == KtSymbolOrigin.DELEGATED } + } } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirDelegatingScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirDelegatingScope.kt index a90f0110792..de240e5eaee 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirDelegatingScope.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirDelegatingScope.kt @@ -42,10 +42,18 @@ internal open class KtFirDelegatingScope( firScope.getCallableSymbols(getPossibleCallableNames().filter(nameFilter), builder) } + override fun getCallableSymbols(names: Collection): Sequence = withValidityAssertion { + firScope.getCallableSymbols(names, builder) + } + override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { firScope.getClassifierSymbols(getPossibleClassifierNames().filter(nameFilter), builder) } + override fun getClassifierSymbols(names: Collection): Sequence = withValidityAssertion { + firScope.getClassifierSymbols(names, builder) + } + override fun getConstructors(): Sequence = withValidityAssertion { firScope.getConstructors(builder) } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirFileScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirFileScope.kt index 1992f380bd4..731cf1fdda7 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirFileScope.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirFileScope.kt @@ -78,6 +78,12 @@ internal class KtFirFileScope( } } + override fun getCallableSymbols(names: Collection): Sequence = withValidityAssertion { + if (names.isEmpty()) return emptySequence() + val namesSet = names.toSet() + return getCallableSymbols { it in namesSet } + } + override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { sequence { owner.firSymbol.fir.declarations.forEach { firDeclaration -> @@ -93,6 +99,12 @@ internal class KtFirFileScope( } } + override fun getClassifierSymbols(names: Collection): Sequence { + if (names.isEmpty()) return emptySequence() + val namesSet = names.toSet() + return getClassifierSymbols { it in namesSet } + } + override fun getConstructors(): Sequence = withValidityAssertion { emptySequence() } override fun getPackageSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirNonStarImportingScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirNonStarImportingScope.kt index 5b0ff1bd243..0a97d080bb6 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirNonStarImportingScope.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirNonStarImportingScope.kt @@ -51,10 +51,18 @@ internal class KtFirNonStarImportingScope( firScope.getCallableSymbols(getPossibleCallableNames().filter(nameFilter), builder) } + override fun getCallableSymbols(names: Collection): Sequence = withValidityAssertion { + firScope.getCallableSymbols(names, builder) + } + override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { firScope.getClassifierSymbols(getPossibleClassifierNames().filter(nameFilter), builder) } + override fun getClassifierSymbols(names: Collection): Sequence = withValidityAssertion { + firScope.getClassifierSymbols(names, builder) + } + override fun getPackageSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { emptySequence() } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirPackageScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirPackageScope.kt index 347ca2ff257..ed6466ebd84 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirPackageScope.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirPackageScope.kt @@ -89,10 +89,18 @@ internal class KtFirPackageScope( firScope.getCallableSymbols(getPossibleCallableNames().filter(nameFilter), analysisSession.firSymbolBuilder) } + override fun getCallableSymbols(names: Collection): Sequence = withValidityAssertion { + firScope.getCallableSymbols(names, analysisSession.firSymbolBuilder) + } + override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { firScope.getClassifierSymbols(getPossibleClassifierNames().filter(nameFilter), analysisSession.firSymbolBuilder) } + override fun getClassifierSymbols(names: Collection): Sequence = withValidityAssertion { + firScope.getClassifierSymbols(names, analysisSession.firSymbolBuilder) + } + override fun getConstructors(): Sequence = withValidityAssertion { emptySequence() } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirStarImportingScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirStarImportingScope.kt index 8f4be51095c..75b46d3d9bc 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirStarImportingScope.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirStarImportingScope.kt @@ -40,10 +40,18 @@ internal class KtFirStarImportingScope( firScope.getCallableSymbols(getPossibleCallableNames().filter(nameFilter), builder) } + override fun getCallableSymbols(names: Collection): Sequence = withValidityAssertion { + firScope.getCallableSymbols(names, builder) + } + override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { firScope.getClassifierSymbols(getPossibleClassifierNames().filter(nameFilter), builder) } + override fun getClassifierSymbols(names: Collection): Sequence = withValidityAssertion { + firScope.getClassifierSymbols(names, builder) + } + override fun getConstructors(): Sequence = withValidityAssertion { emptySequence() } // todo cache? diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/scopes/KtCompositeScope.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/scopes/KtCompositeScope.kt index f3b33d21ffd..f24bf838d1a 100644 --- a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/scopes/KtCompositeScope.kt +++ b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/scopes/KtCompositeScope.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.analysis.api.impl.base.scopes +import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken +import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.scopes.KtScope import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter import org.jetbrains.kotlin.analysis.api.symbols.* -import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken -import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.name.Name class KtCompositeScope( @@ -46,12 +46,26 @@ class KtCompositeScope( } } + override fun getCallableSymbols(names: Collection): Sequence = withValidityAssertion { + if (names.isEmpty()) return emptySequence() + sequence { + subScopes.forEach { yieldAll(it.getCallableSymbols(names)) } + } + } + override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { sequence { subScopes.forEach { yieldAll(it.getClassifierSymbols(nameFilter)) } } } + override fun getClassifierSymbols(names: Collection): Sequence = withValidityAssertion { + if (names.isEmpty()) return emptySequence() + sequence { + subScopes.forEach { yieldAll(it.getClassifierSymbols(names)) } + } + } + override fun getConstructors(): Sequence = withValidityAssertion { sequence { subScopes.forEach { yieldAll(it.getConstructors()) } diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/scopes/KtEmptyScope.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/scopes/KtEmptyScope.kt index f11493bc388..09a2e3a831d 100644 --- a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/scopes/KtEmptyScope.kt +++ b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/scopes/KtEmptyScope.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.analysis.api.impl.base.scopes +import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken +import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.scopes.KtScope import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter import org.jetbrains.kotlin.analysis.api.symbols.* -import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken -import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.name.Name class KtEmptyScope(override val token: KtLifetimeToken) : KtScope { @@ -33,10 +33,18 @@ class KtEmptyScope(override val token: KtLifetimeToken) : KtScope { return emptySequence() } + override fun getCallableSymbols(names: Collection): Sequence = withValidityAssertion { + return emptySequence() + } + override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { return emptySequence() } + override fun getClassifierSymbols(names: Collection): Sequence = withValidityAssertion { + return emptySequence() + } + override fun getConstructors(): Sequence = withValidityAssertion { return emptySequence() } diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/scopes/KtScope.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/scopes/KtScope.kt index 20457d35faf..5dc9d72ecbe 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/scopes/KtScope.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/scopes/KtScope.kt @@ -5,9 +5,8 @@ package org.jetbrains.kotlin.analysis.api.scopes -import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner -import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion +import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.name.Name @@ -24,16 +23,55 @@ public interface KtScope : KtScopeLike { } /** - * Return a sequence of [KtCallableSymbol] which current scope contain if declaration name matches [nameFilter] + * Return a sequence of [KtCallableSymbol] which current scope contain if declaration name matches [nameFilter]. + * + * This function needs to retrieve a set of all possible names before processing the scope. + * The overload with `names: Collection` should be used when the candidate name set is known. */ public fun getCallableSymbols(nameFilter: KtScopeNameFilter = { true }): Sequence + /** + * Return a sequence of [KtCallableSymbol] which current scope contain, if declaration name present in [names] + * + * This implementation is more optimal than the one with `nameFilter` and should be used when the candidate name set is known. + */ + public fun getCallableSymbols(names: Collection): Sequence + + /** + * Return a sequence of [KtCallableSymbol] which current scope contain, if declaration name present in [names] + * + * @see getCallableSymbols + */ + public fun getCallableSymbols(vararg names: Name): Sequence = + getCallableSymbols(names.toList()) + /** * Return a sequence of [KtClassifierSymbol] which current scope contain if classifier name matches [nameFilter]. The sequence includes: * nested classes, inner classes, nested type aliases for the class scope, and top-level classes and top-level type aliases for file scope. + * + * This function needs to retrieve a set of all possible names before processing the scope. + * The overload with `names: Collection` should be used when the candidate name set is known. */ public fun getClassifierSymbols(nameFilter: KtScopeNameFilter = { true }): Sequence + /** + * Return a sequence of [KtClassifierSymbol] which current scope contains, if classifier name present in [names]. + * + * The sequence includes: nested classes, inner classes, nested type aliases for the class scope, + * and top-level classes and top-level type aliases for file scope. + * + * This implementation is more optimal than the one with `nameFilter` and should be used when the candidate name set is known. + */ + public fun getClassifierSymbols(names: Collection): Sequence + + /** + * Return a sequence of [KtClassifierSymbol] which current scope contains, if classifier name present in [names]. + * + * @see getClassifierSymbols + */ + public fun getClassifierSymbols(vararg names: Name): Sequence = + getClassifierSymbols(names.toList()) + /** * Return a sequence of [KtConstructorSymbol] which current scope contain */