FIR IDE: add type parameters support to scopes

This commit is contained in:
Ilya Kirillov
2020-09-01 19:17:43 +03:00
parent c0e9f05921
commit 6d18bb6ba2
9 changed files with 51 additions and 55 deletions
@@ -14,24 +14,24 @@ import org.jetbrains.kotlin.name.Name
interface KtScope : ValidityTokenOwner {
// TODO check that names are accessible
// maybe return some kind of lazy set
fun getAllNames(): Set<Name> = withValidityAssertion { getCallableNames() + getClassLikeSymbolNames() }
fun getAllNames(): Set<Name> = withValidityAssertion { getCallableNames() + getClassifierNames() }
fun getCallableNames(): Set<Name>
fun getClassLikeSymbolNames(): Set<Name>
fun getClassifierNames(): Set<Name>
fun getAllSymbols(): Sequence<KtSymbol> = withValidityAssertion {
sequence {
yieldAll(getCallableSymbols())
yieldAll(getClassClassLikeSymbols())
yieldAll(getClassifierSymbols())
}
}
fun getCallableSymbols(): Sequence<KtCallableSymbol>
fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol>
fun getClassifierSymbols(): Sequence<KtClassifierSymbol>
fun containsName(name: Name): Boolean = withValidityAssertion {
name in getCallableNames() || name in getClassLikeSymbolNames()
name in getCallableNames() || name in getClassifierNames()
}
}
@@ -9,8 +9,13 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
sealed class KtClassifierSymbol : KtSymbol, KtNamedSymbol
sealed class KtClassLikeSymbol : KtSymbol, KtNamedSymbol, KtSymbolWithKind {
abstract class KtTypeParameterSymbol : KtClassifierSymbol(), KtNamedSymbol {
abstract override fun createPointer(): KtSymbolPointer<KtTypeParameterSymbol>
}
sealed class KtClassLikeSymbol : KtClassifierSymbol(), KtNamedSymbol, KtSymbolWithKind {
abstract val classIdIfNonLocal: ClassId?
abstract override fun createPointer(): KtSymbolPointer<KtClassLikeSymbol>
@@ -34,4 +39,4 @@ abstract class KtClassOrObjectSymbol : KtClassLikeSymbol(),
enum class KtClassKind {
CLASS, ENUM_CLASS, ENUM_ENTRY, ANNOTATION_CLASS, OBJECT, COMPANION_OBJECT, INTERFACE
}
}
@@ -1,15 +0,0 @@
/*
* Copyright 2010-2020 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.
*/
package org.jetbrains.kotlin.idea.frontend.api.symbols
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtNamedSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
abstract class KtTypeParameterSymbol : KtSymbol, KtNamedSymbol {
abstract override fun createPointer(): KtSymbolPointer<KtTypeParameterSymbol>
}
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
@@ -108,6 +109,13 @@ internal class KtSymbolByFirBuilder private constructor(
TODO(fir::class.toString())
}
fun buildClassifierSymbol(firSymbol: FirClassifierSymbol<*>): KtClassifierSymbol = when (val fir = firSymbol.fir) {
is FirClassLikeDeclaration -> buildClassLikeSymbol(fir)
is FirTypeParameter -> buildTypeParameterSymbol(fir)
else ->
TODO(fir::class.toString())
}
fun buildClassSymbol(fir: FirRegularClass) = symbolsCache.cache(fir) { KtFirClassOrObjectSymbol(fir, resolveState, token, this) }
// TODO it can be a constructor parameter, which may be split into parameter & property
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.idea.frontend.api.scopes.KtCompositeScope
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScope
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
@@ -34,9 +35,9 @@ class KtFirCompositeScope(
}
}
override fun getClassLikeSymbolNames(): Set<Name> = withValidityAssertion {
override fun getClassifierNames(): Set<Name> = withValidityAssertion {
buildSet {
subScopes.flatMapTo(this) { it.getClassLikeSymbolNames() }
subScopes.flatMapTo(this) { it.getClassifierNames() }
}
}
@@ -52,9 +53,9 @@ class KtFirCompositeScope(
}
}
override fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol> = withValidityAssertion {
override fun getClassifierSymbols(): Sequence<KtClassifierSymbol> = withValidityAssertion {
sequence {
subScopes.forEach { yieldAll(it.getClassClassLikeSymbols()) }
subScopes.forEach { yieldAll(it.getClassifierSymbols()) }
}
}
@@ -5,15 +5,10 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.scopes
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
@@ -21,6 +16,7 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScope
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
@@ -32,7 +28,7 @@ internal abstract class KtFirDelegatingScope<S>(
abstract val firScope: S
private val allNamesCached by cached {
getCallableNames() + getClassLikeSymbolNames()
getCallableNames() + getClassifierNames()
}
override fun getAllNames(): Set<Name> = allNamesCached
@@ -41,7 +37,7 @@ internal abstract class KtFirDelegatingScope<S>(
firScope.getCallableNames()
}
override fun getClassLikeSymbolNames(): Set<Name> = withValidityAssertion {
override fun getClassifierNames(): Set<Name> = withValidityAssertion {
firScope.getClassifierNames()
}
@@ -49,8 +45,8 @@ internal abstract class KtFirDelegatingScope<S>(
firScope.getCallableSymbols(getCallableNames(), builder)
}
override fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol> = withValidityAssertion {
firScope.getClassLikeSymbols(getClassLikeSymbolNames(), builder)
override fun getClassifierSymbols(): Sequence<KtClassifierSymbol> = withValidityAssertion {
firScope.getClassifierSymbols(getClassifierNames(), builder)
}
override fun containsName(name: Name): Boolean = withValidityAssertion {
@@ -80,14 +76,13 @@ internal fun FirScope.getCallableSymbols(callableNames: Collection<Name>, builde
}
}
internal fun FirScope.getClassLikeSymbols(classLikeNames: Collection<Name>, builder: KtSymbolByFirBuilder) = sequence {
classLikeNames.forEach { name ->
val classLikeSymbols = mutableListOf<KtClassLikeSymbol>()
processClassifiersByName(name) { firSymbol ->
(firSymbol.fir as? FirClassLikeDeclaration<*>)?.let {
classLikeSymbols.add(builder.buildClassLikeSymbol(it))
internal fun FirScope.getClassifierSymbols(classLikeNames: Collection<Name>, builder: KtSymbolByFirBuilder): Sequence<KtClassifierSymbol> =
sequence {
classLikeNames.forEach { name ->
val classifierSymbols = mutableListOf<KtClassifierSymbol>()
processClassifiersByName(name) { firSymbol ->
classifierSymbols.add(builder.buildClassifierSymbol(firSymbol))
}
yieldAll(classifierSymbols)
}
yieldAll(classLikeSymbols)
}
}
}
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.idea.frontend.api.scopes.KtNonStarImportingScope
import org.jetbrains.kotlin.idea.frontend.api.scopes.NonStarImport
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
@@ -46,8 +47,8 @@ internal class KtFirNonStarImportingScope(
firScope.getCallableSymbols(getCallableNames(), builder)
}
override fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol> = withValidityAssertion {
firScope.getClassLikeSymbols(getClassLikeSymbolNames(), builder)
override fun getClassifierSymbols(): Sequence<KtClassifierSymbol> = withValidityAssertion {
firScope.getClassifierSymbols(getClassifierNames(), builder)
}
@@ -55,7 +56,7 @@ internal class KtFirNonStarImportingScope(
imports.mapNotNullTo(hashSetOf()) { it.callableName }
}
override fun getClassLikeSymbolNames(): Set<Name> = withValidityAssertion {
override fun getClassifierNames(): Set<Name> = withValidityAssertion {
imports.mapNotNullTo((hashSetOf())) { it.relativeClassName?.shortName() }
}
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtPackageScope
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelClassByPackageIndex
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionByPackageIndex
@@ -39,7 +40,7 @@ internal class KtFirPackageScope(
}
}
override fun getClassLikeSymbolNames(): Set<Name> = withValidityAssertion {
override fun getClassifierNames(): Set<Name> = withValidityAssertion {
KotlinTopLevelClassByPackageIndex.getInstance()[fqName.asString(), project, firScope.session.searchScope]
.mapNotNullTo(hashSetOf()) { it.nameAsName }
}
@@ -48,7 +49,7 @@ internal class KtFirPackageScope(
firScope.getCallableSymbols(getCallableNames(), builder)
}
override fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol> = withValidityAssertion {
firScope.getClassLikeSymbols(getClassLikeSymbolNames(), builder)
override fun getClassifierSymbols(): Sequence<KtClassifierSymbol> = withValidityAssertion {
firScope.getClassifierSymbols(getClassifierNames(), builder)
}
}
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.idea.frontend.api.scopes.KtStarImportingScope
import org.jetbrains.kotlin.idea.frontend.api.scopes.StarImport
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelClassByPackageIndex
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionByPackageIndex
@@ -55,8 +55,8 @@ internal class KtFirStarImportingScope(
firScope.getCallableSymbols(getCallableNames(), builder)
}
override fun getClassClassLikeSymbols(): Sequence<KtClassLikeSymbol> = withValidityAssertion {
firScope.getClassLikeSymbols(getClassLikeSymbolNames(), builder)
override fun getClassifierSymbols(): Sequence<KtClassifierSymbol> = withValidityAssertion {
firScope.getClassifierSymbols(getClassifierNames(), builder)
}
// todo cache?
@@ -72,7 +72,7 @@ internal class KtFirStarImportingScope(
}
}
override fun getClassLikeSymbolNames(): Set<Name> = withValidityAssertion {
override fun getClassifierNames(): Set<Name> = withValidityAssertion {
imports.flatMapTo(hashSetOf()) { import ->
if (import.relativeClassName == null) {
packageHelper.getPackageTopLevelClassifiers(import.packageFqName)