FIR IDE: add KDoc for KtScope, choose better names for KtScope members

This commit is contained in:
Ilya Kirillov
2021-05-04 13:13:08 +02:00
committed by TeamCityServer
parent f9087a8ab1
commit 90798d8857
10 changed files with 79 additions and 44 deletions
@@ -375,7 +375,7 @@ private fun alreadyHasImport(file: KtFile, nameToImport: CallableId): Boolean {
withAllowedResolve { withAllowedResolve {
analyse(file) { analyse(file) {
val scopes = file.getScopeContextForFile().scopes val scopes = file.getScopeContextForFile().scopes
if (!scopes.containsName(nameToImport.callableName)) return false if (!scopes.mayContainName(nameToImport.callableName)) return false
return scopes return scopes
.getCallableSymbols { it == nameToImport.callableName } .getCallableSymbols { it == nameToImport.callableName }
@@ -13,15 +13,32 @@ import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
interface KtScope : ValidityTokenOwner { interface KtScope : ValidityTokenOwner {
// TODO check that names are accessible /**
// maybe return some kind of lazy set * Returns a **subset** of names which current scope may contain.
fun getAllNames(): Set<Name> = withValidityAssertion { getCallableNames() + getClassifierNames() } * In other words `ALL_NAMES(scope)` is a subset of `scope.getAllNames()`
*/
fun getAllPossibleNames(): Set<Name> = withValidityAssertion {
getPossibleCallableNames() + getPossibleClassifierNames()
}
fun getCallableNames(): Set<Name> /**
fun getClassifierNames(): Set<Name> * Returns a **subset** of callable names which current scope may contain.
* In other words `ALL_CALLABLE_NAMES(scope)` is a subset of `scope.getCallableNames()`
*/
fun getPossibleCallableNames(): Set<Name>
/**
* Returns a **subset** of classifier names which current scope may contain.
* In other words `ALL_CLASSIFIER_NAMES(scope)` is a subset of `scope.getClassifierNames()`
*/
fun getPossibleClassifierNames(): Set<Name>
/**
* Return a sequence of all [KtSymbol] which current scope contain
*/
fun getAllSymbols(): Sequence<KtSymbol> = withValidityAssertion { fun getAllSymbols(): Sequence<KtSymbol> = withValidityAssertion {
sequence { sequence {
yieldAll(getCallableSymbols()) yieldAll(getCallableSymbols())
@@ -30,12 +47,28 @@ interface KtScope : ValidityTokenOwner {
} }
} }
/**
* Return a sequence of [KtCallableSymbol] which current scope contain if declaration name matches [nameFilter]
*/
fun getCallableSymbols(nameFilter: KtScopeNameFilter = { true }): Sequence<KtCallableSymbol> fun getCallableSymbols(nameFilter: KtScopeNameFilter = { true }): Sequence<KtCallableSymbol>
/**
* Return a sequence of [KtClassifierSymbol] which current scope contain if declaration name matches [nameFilter]
*/
fun getClassifierSymbols(nameFilter: KtScopeNameFilter = { true }): Sequence<KtClassifierSymbol> fun getClassifierSymbols(nameFilter: KtScopeNameFilter = { true }): Sequence<KtClassifierSymbol>
/**
* Return a sequence of [KtConstructorSymbol] which current scope contain
*/
fun getConstructors(): Sequence<KtConstructorSymbol> fun getConstructors(): Sequence<KtConstructorSymbol>
fun containsName(name: Name): Boolean = withValidityAssertion { /**
name in getCallableNames() || name in getClassifierNames() * return true if the scope may contain name, false otherwise.
*
* In other words `(mayContainName(name) == false) => (name !in scope)`; vice versa is not always true
*/
fun mayContainName(name: Name): Boolean = withValidityAssertion {
name in getPossibleCallableNames() || name in getPossibleClassifierNames()
} }
} }
@@ -24,21 +24,21 @@ class KtFirCompositeScope(
override val subScopes: List<KtScope>, override val subScopes: List<KtScope>,
override val token: ValidityToken override val token: ValidityToken
) : KtCompositeScope, ValidityTokenOwner { ) : KtCompositeScope, ValidityTokenOwner {
override fun getAllNames(): Set<Name> = withValidityAssertion { override fun getAllPossibleNames(): Set<Name> = withValidityAssertion {
buildSet { buildSet {
subScopes.flatMapTo(this) { it.getAllNames() } subScopes.flatMapTo(this) { it.getAllPossibleNames() }
} }
} }
override fun getCallableNames(): Set<Name> = withValidityAssertion { override fun getPossibleCallableNames(): Set<Name> = withValidityAssertion {
buildSet { buildSet {
subScopes.flatMapTo(this) { it.getCallableNames() } subScopes.flatMapTo(this) { it.getPossibleCallableNames() }
} }
} }
override fun getClassifierNames(): Set<Name> = withValidityAssertion { override fun getPossibleClassifierNames(): Set<Name> = withValidityAssertion {
buildSet { buildSet {
subScopes.flatMapTo(this) { it.getClassifierNames() } subScopes.flatMapTo(this) { it.getPossibleClassifierNames() }
} }
} }
@@ -66,7 +66,7 @@ class KtFirCompositeScope(
} }
} }
override fun containsName(name: Name): Boolean = withValidityAssertion { override fun mayContainName(name: Name): Boolean = withValidityAssertion {
subScopes.any { it.containsName(name) } subScopes.any { it.mayContainName(name) }
} }
} }
@@ -29,33 +29,33 @@ internal abstract class KtFirDelegatingScope<S>(
abstract val firScope: S abstract val firScope: S
private val allNamesCached by cached { private val allNamesCached by cached {
getCallableNames() + getClassifierNames() getPossibleCallableNames() + getPossibleClassifierNames()
} }
override fun getAllNames(): Set<Name> = allNamesCached override fun getAllPossibleNames(): Set<Name> = allNamesCached
override fun getCallableNames(): Set<Name> = withValidityAssertion { override fun getPossibleCallableNames(): Set<Name> = withValidityAssertion {
firScope.getCallableNames() firScope.getCallableNames()
} }
override fun getClassifierNames(): Set<Name> = withValidityAssertion { override fun getPossibleClassifierNames(): Set<Name> = withValidityAssertion {
firScope.getClassifierNames() firScope.getClassifierNames()
} }
override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = withValidityAssertion { override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = withValidityAssertion {
firScope.getCallableSymbols(getCallableNames().filter(nameFilter), builder) firScope.getCallableSymbols(getPossibleCallableNames().filter(nameFilter), builder)
} }
override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence<KtClassifierSymbol> = withValidityAssertion { override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence<KtClassifierSymbol> = withValidityAssertion {
firScope.getClassifierSymbols(getClassifierNames().filter(nameFilter), builder) firScope.getClassifierSymbols(getPossibleClassifierNames().filter(nameFilter), builder)
} }
override fun getConstructors(): Sequence<KtConstructorSymbol> = withValidityAssertion { override fun getConstructors(): Sequence<KtConstructorSymbol> = withValidityAssertion {
firScope.getConstructors(builder) firScope.getConstructors(builder)
} }
override fun containsName(name: Name): Boolean = withValidityAssertion { override fun mayContainName(name: Name): Boolean = withValidityAssertion {
name in getAllNames() name in getAllPossibleNames()
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -17,9 +17,9 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMember
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
internal class KtFirEmptyMemberScope(override val owner: KtSymbolWithMembers) : KtMemberScope, KtDeclaredMemberScope, ValidityTokenOwner { internal class KtFirEmptyMemberScope(override val owner: KtSymbolWithMembers) : KtMemberScope, KtDeclaredMemberScope, ValidityTokenOwner {
override fun getCallableNames(): Set<Name> = emptySet() override fun getPossibleCallableNames(): Set<Name> = emptySet()
override fun getClassifierNames(): Set<Name> = emptySet() override fun getPossibleClassifierNames(): Set<Name> = emptySet()
override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> =
emptySequence() emptySequence()
@@ -30,6 +30,8 @@ internal class KtFirEmptyMemberScope(override val owner: KtSymbolWithMembers) :
override fun getConstructors(): Sequence<KtConstructorSymbol> = override fun getConstructors(): Sequence<KtConstructorSymbol> =
emptySequence() emptySequence()
override fun mayContainName(name: Name): Boolean = false
override val token: ValidityToken override val token: ValidityToken
get() = owner.token get() = owner.token
} }
@@ -33,7 +33,7 @@ internal class KtFirFileScope(
_callableNames + _classifierNames _callableNames + _classifierNames
} }
override fun getAllNames(): Set<Name> = allNamesCached override fun getAllPossibleNames(): Set<Name> = allNamesCached
private val _callableNames: Set<Name> by cached { private val _callableNames: Set<Name> by cached {
val result = mutableSetOf<Name>() val result = mutableSetOf<Name>()
@@ -49,7 +49,7 @@ internal class KtFirFileScope(
result result
} }
override fun getCallableNames(): Set<Name> = _callableNames override fun getPossibleCallableNames(): Set<Name> = _callableNames
private val _classifierNames: Set<Name> by cached { private val _classifierNames: Set<Name> by cached {
val result = mutableSetOf<Name>() val result = mutableSetOf<Name>()
@@ -61,7 +61,7 @@ internal class KtFirFileScope(
result result
} }
override fun getClassifierNames(): Set<Name> = _classifierNames override fun getPossibleClassifierNames(): Set<Name> = _classifierNames
override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = withValidityAssertion { override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = withValidityAssertion {
owner.firRef.withFir { owner.firRef.withFir {
@@ -45,20 +45,20 @@ internal class KtFirNonStarImportingScope(
} }
override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = withValidityAssertion { override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = withValidityAssertion {
firScope.getCallableSymbols(getCallableNames().filter(nameFilter), builder) firScope.getCallableSymbols(getPossibleCallableNames().filter(nameFilter), builder)
} }
override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence<KtClassifierSymbol> = withValidityAssertion { override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence<KtClassifierSymbol> = withValidityAssertion {
firScope.getClassifierSymbols(getClassifierNames().filter(nameFilter), builder) firScope.getClassifierSymbols(getPossibleClassifierNames().filter(nameFilter), builder)
} }
override fun getConstructors(): Sequence<KtConstructorSymbol> = emptySequence() override fun getConstructors(): Sequence<KtConstructorSymbol> = emptySequence()
override fun getCallableNames(): Set<Name> = withValidityAssertion { override fun getPossibleCallableNames(): Set<Name> = withValidityAssertion {
imports.mapNotNullTo(hashSetOf()) { it.callableName } imports.mapNotNullTo(hashSetOf()) { it.callableName }
} }
override fun getClassifierNames(): Set<Name> = withValidityAssertion { override fun getPossibleClassifierNames(): Set<Name> = withValidityAssertion {
imports.mapNotNullTo((hashSetOf())) { it.relativeClassName?.shortName() } imports.mapNotNullTo((hashSetOf())) { it.relativeClassName?.shortName() }
} }
@@ -32,7 +32,7 @@ internal class KtFirPackageScope(
private val firScope by weakRef(firScope) private val firScope by weakRef(firScope)
override val fqName: FqName get() = firScope.fqName override val fqName: FqName get() = firScope.fqName
override fun getCallableNames() = withValidityAssertion { override fun getPossibleCallableNames() = withValidityAssertion {
hashSetOf<Name>().apply { hashSetOf<Name>().apply {
KotlinTopLevelPropertyByPackageIndex.getInstance()[fqName.asString(), project, firScope.session.searchScope] KotlinTopLevelPropertyByPackageIndex.getInstance()[fqName.asString(), project, firScope.session.searchScope]
.mapNotNullTo(this) { it.nameAsName } .mapNotNullTo(this) { it.nameAsName }
@@ -41,17 +41,17 @@ internal class KtFirPackageScope(
} }
} }
override fun getClassifierNames(): Set<Name> = withValidityAssertion { override fun getPossibleClassifierNames(): Set<Name> = withValidityAssertion {
KotlinTopLevelClassByPackageIndex.getInstance()[fqName.asString(), project, firScope.session.searchScope] KotlinTopLevelClassByPackageIndex.getInstance()[fqName.asString(), project, firScope.session.searchScope]
.mapNotNullTo(hashSetOf()) { it.nameAsName } .mapNotNullTo(hashSetOf()) { it.nameAsName }
} }
override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = withValidityAssertion { override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = withValidityAssertion {
firScope.getCallableSymbols(getCallableNames().filter(nameFilter), builder) firScope.getCallableSymbols(getPossibleCallableNames().filter(nameFilter), builder)
} }
override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence<KtClassifierSymbol> = withValidityAssertion { override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence<KtClassifierSymbol> = withValidityAssertion {
firScope.getClassifierSymbols(getClassifierNames().filter(nameFilter), builder) firScope.getClassifierSymbols(getPossibleClassifierNames().filter(nameFilter), builder)
} }
override fun getConstructors(): Sequence<KtConstructorSymbol> = emptySequence() override fun getConstructors(): Sequence<KtConstructorSymbol> = emptySequence()
@@ -50,18 +50,18 @@ internal class KtFirStarImportingScope(
} }
override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = withValidityAssertion { override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> = withValidityAssertion {
firScope.getCallableSymbols(getCallableNames().filter(nameFilter), builder) firScope.getCallableSymbols(getPossibleCallableNames().filter(nameFilter), builder)
} }
override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence<KtClassifierSymbol> = withValidityAssertion { override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence<KtClassifierSymbol> = withValidityAssertion {
firScope.getClassifierSymbols(getClassifierNames().filter(nameFilter), builder) firScope.getClassifierSymbols(getPossibleClassifierNames().filter(nameFilter), builder)
} }
override fun getConstructors(): Sequence<KtConstructorSymbol> = emptySequence() override fun getConstructors(): Sequence<KtConstructorSymbol> = emptySequence()
// todo cache? // todo cache?
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
override fun getCallableNames(): Set<Name> = withValidityAssertion { override fun getPossibleCallableNames(): Set<Name> = withValidityAssertion {
imports.flatMapTo(hashSetOf()) { import: Import -> imports.flatMapTo(hashSetOf()) { import: Import ->
if (import.relativeClassName == null) { // top level callable if (import.relativeClassName == null) { // top level callable
packageHelper.getPackageTopLevelCallables(import.packageFqName) packageHelper.getPackageTopLevelCallables(import.packageFqName)
@@ -72,7 +72,7 @@ internal class KtFirStarImportingScope(
} }
} }
override fun getClassifierNames(): Set<Name> = withValidityAssertion { override fun getPossibleClassifierNames(): Set<Name> = withValidityAssertion {
imports.flatMapTo(hashSetOf()) { import -> imports.flatMapTo(hashSetOf()) { import ->
if (import.relativeClassName == null) { if (import.relativeClassName == null) {
packageHelper.getPackageTopLevelClassifiers(import.packageFqName) packageHelper.getPackageTopLevelClassifiers(import.packageFqName)
@@ -25,9 +25,9 @@ abstract class AbstractFileScopeTest : KotlinLightCodeInsightFixtureTestCase() {
val scope = symbol.getFileScope() val scope = symbol.getFileScope()
val renderedSymbol = DebugSymbolRenderer.render(symbol) val renderedSymbol = DebugSymbolRenderer.render(symbol)
val callableNames = scope.getCallableNames() val callableNames = scope.getPossibleCallableNames()
val renderedCallables = scope.getCallableSymbols().map { DebugSymbolRenderer.render(it) } val renderedCallables = scope.getCallableSymbols().map { DebugSymbolRenderer.render(it) }
val classifierNames = scope.getClassifierNames() val classifierNames = scope.getPossibleClassifierNames()
val renderedClassifiers = scope.getClassifierSymbols().map { DebugSymbolRenderer.render(it) } val renderedClassifiers = scope.getClassifierSymbols().map { DebugSymbolRenderer.render(it) }
"FILE SYMBOL:\n" + renderedSymbol + "FILE SYMBOL:\n" + renderedSymbol +