FIR IDE: introduce symbol API

This commit is contained in:
Ilya Kirillov
2020-06-25 15:59:39 +03:00
parent ba948cda38
commit 82866176fb
28 changed files with 906 additions and 9 deletions
@@ -13,10 +13,22 @@ interface Invalidatable {
fun isValid(): Boolean fun isValid(): Boolean
fun invalidationReason(): String fun invalidationReason(): String
}
fun assertIsValid() { @Suppress("NOTHING_TO_INLINE")
assert(isValid()) { "Access to invalid $this, invalidation reason is ${invalidationReason()}" } inline fun Invalidatable.assertIsValid() {
} assert(isValid()) { "Access to invalid $this, invalidation reason is ${invalidationReason()}" }
}
inline fun <R> Invalidatable.withValidityAssertion(action: () -> R): R {
assertIsValid()
return action()
}
interface InvalidatableByValidityToken : Invalidatable {
val token: Invalidatable
override fun isValid(): Boolean = token.isValid()
override fun invalidationReason(): String = token.invalidationReason()
} }
class ReadActionConfinementValidityToken(project: Project) : Invalidatable { class ReadActionConfinementValidityToken(project: Project) : Invalidatable {
@@ -0,0 +1,25 @@
/*
* 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.name.ClassId
abstract class KtClassLikeSymbol : KtSymbol, KtNamedSymbol, KtSymbolWithKind {
abstract val classId: ClassId
}
abstract class KtTypeAliasSymbol : KtClassLikeSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.TOP_LEVEL
}
abstract class KtClassOrObjectSymbol : KtClassLikeSymbol(), KtSymbolWithTypeParameters {
abstract val classKind: KtClassKind
}
enum class KtClassKind {
CLASS, ABSTRACT_CLASS, ENUM_CLASS, ENUM_ENTRY, ANNOTATION_CLASS, OBJECT, COMPANION_OBJECT, INTERFACE
}
@@ -0,0 +1,30 @@
/*
* 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.name.FqName
sealed class KtFunctionLikeSymbol : KtTypedSymbol, KtSymbolWithKind {
abstract val valueParameters: List<KtParameterSymbol>
}
abstract class KtAnonymousFunctionSymbol : KtFunctionLikeSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
}
abstract class KtFunctionSymbol : KtFunctionLikeSymbol(), KtNamedSymbol, KtPossibleExtensionSymbol, KtSymbolWithTypeParameters {
abstract val isSuspend: Boolean
abstract val isOperator: Boolean
abstract val fqName: FqName?
abstract override val valueParameters: List<KtSimpleFunctionParameterSymbol>
}
abstract class KtConstructorSymbol : KtFunctionLikeSymbol() {
abstract override val valueParameters: List<KtConstructorParameterSymbol>
abstract val isPrimary: Boolean
abstract val owner: KtClassOrObjectSymbol
}
@@ -0,0 +1,18 @@
/*
* 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 com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
interface KtSymbol : Invalidatable {
val origin: KtSymbolOrigin
val psi: PsiElement?
}
enum class KtSymbolOrigin {
SOURCE, LIBRARY, JAVA, SAM_CONSTRUCTOR
}
@@ -0,0 +1,41 @@
/*
* 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.Invalidatable
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.*
abstract class KtSymbolProvider : Invalidatable {
open fun getSymbol(psi: KtDeclaration): KtSymbol = when (psi) {
is KtParameter -> getParameterSymbol(psi)
is KtNamedFunction -> getFunctionSymbol(psi)
is KtConstructor<*> -> getConstructorSymbol(psi)
is KtTypeParameter -> getTypeParameterSymbol(psi)
is KtTypeAlias -> getTypeAliasSymbol(psi)
is KtEnumEntry -> getEnumEntrySymbol(psi)
is KtLambdaExpression -> getAnonymousFunctionSymbol(psi)
is KtProperty -> getVariableSymbol(psi)
is KtClassOrObject -> getClassOrObjectSymbol(psi)
else -> error("Cannot build symbol for ${psi::class}")
}
abstract fun getParameterSymbol(psi: KtParameter): KtParameterSymbol
abstract fun getFunctionSymbol(psi: KtNamedFunction): KtFunctionSymbol
abstract fun getConstructorSymbol(psi: KtConstructor<*>): KtConstructorSymbol
abstract fun getTypeParameterSymbol(psi: KtTypeParameter): KtTypeParameterSymbol
abstract fun getTypeAliasSymbol(psi: KtTypeAlias): KtTypeAliasSymbol
abstract fun getEnumEntrySymbol(psi: KtEnumEntry): KtEnumEntrySymbol
abstract fun getAnonymousFunctionSymbol(psi: KtNamedFunction): KtAnonymousFunctionSymbol
abstract fun getAnonymousFunctionSymbol(psi: KtLambdaExpression): KtAnonymousFunctionSymbol
abstract fun getVariableSymbol(psi: KtProperty): KtVariableSymbol
abstract fun getClassOrObjectSymbol(psi: KtClassOrObject): KtClassOrObjectSymbol
/**
* @return symbol with specified [classId] or `null` in case such symbol is not found
*/
abstract fun getClassOrObjectSymbolByClassId(classId: ClassId): KtClassOrObjectSymbol?
}
@@ -0,0 +1,10 @@
/*
* 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
abstract class KtTypeParameterSymbol : KtSymbol, KtNamedSymbol
@@ -0,0 +1,41 @@
/*
* 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.name.FqName
abstract class KtVariableLikeSymbol : KtTypedSymbol, KtNamedSymbol, KtSymbolWithKind
abstract class KtEnumEntrySymbol : KtVariableLikeSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
}
abstract class KtParameterSymbol : KtVariableLikeSymbol()
abstract class KtVariableSymbol : KtVariableLikeSymbol() {
abstract val isVal: Boolean
}
abstract class KtFieldSymbol : KtVariableSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
}
// TODO getters & setters
abstract class KtPropertySymbol : KtVariableSymbol(), KtPossibleExtensionSymbol {
abstract val fqName: FqName
}
abstract class KtLocalVariableSymbol : KtVariableSymbol()
abstract class KtSimpleFunctionParameterSymbol : KtParameterSymbol()
abstract class KtConstructorParameterSymbol : KtParameterSymbol(), KtNamedSymbol {
abstract val constructorParameterKind: KtConstructorParameterSymbolKind
}
enum class KtConstructorParameterSymbolKind {
VAL_PROPERTY, VAR_PROPERTY, NON_PROPERTY
}
@@ -0,0 +1,34 @@
/*
* 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.TypeInfo
import org.jetbrains.kotlin.name.Name
interface KtNamedSymbol : KtSymbol {
val name: Name
}
interface KtSymbolWithKind : KtSymbol {
val symbolKind: KtSymbolKind
}
enum class KtSymbolKind {
TOP_LEVEL, MEMBER, LOCAL
}
interface KtTypedSymbol : KtSymbol {
val type: TypeInfo
}
interface KtPossibleExtensionSymbol {
val isExtension: Boolean
val receiverType: TypeInfo?
}
interface KtSymbolWithTypeParameters {
val typeParameters: List<KtTypeParameterSymbol>
}
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.idea.frontend.api.ClassTypeExpectedException import org.jetbrains.kotlin.idea.frontend.api.*
import org.jetbrains.kotlin.idea.frontend.api.ErrorTypeClassIdAccessException
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
@@ -12,7 +12,6 @@ import com.intellij.psi.PsiField
import com.intellij.psi.PsiMethod import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
@@ -0,0 +1,73 @@
/*
* 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.fir
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.idea.frontend.api.*
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirLocalVariableSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirFunctionSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirFunctionValueParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
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.KtVariableSymbol
internal class KtSymbolByFirBuilder(private val validityToken: Invalidatable) {
fun buildSymbol(fir: FirDeclaration): KtSymbol = when (fir) {
is FirRegularClass -> buildClassSymbol(fir)
is FirSimpleFunction -> buildFunctionSymbol(fir)
is FirProperty -> buildPropertySymbol(fir)
is FirValueParameterImpl -> buildParameterSymbol(fir)
is FirConstructor -> buildFirConstructorSymbol(fir)
is FirTypeParameter -> buildFirTypeParameterSymbol(fir)
is FirTypeAlias -> buildFirTypeAliasSymbol(fir)
is FirEnumEntry -> buildFirEnumEntrySymbol(fir)
is FirField -> buildFirFieldSymbol(fir)
is FirAnonymousFunction -> buildFirAnonymousFunction(fir)
else ->
TODO(fir::class.toString())
}
fun buildClassSymbol(fir: FirRegularClass) = KtFirClassOrObjectSymbol(fir, validityToken)
// TODO it can be a constructor parameter, which may be split into parameter & property
// we should handle them both
fun buildParameterSymbol(fir: FirValueParameterImpl) = KtFirFunctionValueParameterSymbol(fir, validityToken)
fun buildFirConstructorParameter(fir: FirValueParameterImpl) = KtFirConstructorValueParameterSymbol(fir, validityToken)
fun buildFunctionSymbol(fir: FirSimpleFunction) = KtFirFunctionSymbol(fir, validityToken, this)
fun buildFirConstructorSymbol(fir: FirConstructor) = KtFirConstructorSymbol(fir, validityToken, this)
fun buildFirTypeParameterSymbol(fir: FirTypeParameter) = KtFirTypeParameterSymbol(fir, validityToken)
fun buildFirTypeAliasSymbol(fir: FirTypeAlias) = KtFirTypeAliasSymbol(fir, validityToken)
fun buildFirEnumEntrySymbol(fir: FirEnumEntry) = KtFirEnumEntrySymbol(fir, validityToken)
fun buildFirFieldSymbol(fir: FirField) = KtFirFieldSymbol(fir, validityToken)
fun buildFirAnonymousFunction(fir: FirAnonymousFunction) = KtFirAnonymousFunctionSymbol(fir, validityToken, this)
fun buildPropertySymbol(fir: FirProperty): KtVariableSymbol {
return when {
fir.isLocal -> KtFirLocalVariableSymbol(fir, validityToken)
else -> KtFirPropertySymbol(fir, validityToken)
}
}
}
internal fun FirElement.buildSymbol(builder: KtSymbolByFirBuilder) =
(this as? FirDeclaration)?.let(builder::buildSymbol)
internal fun FirDeclaration.buildSymbol(builder: KtSymbolByFirBuilder) =
builder.buildSymbol(this)
@@ -0,0 +1,39 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
internal class KtFirAnonymousFunctionSymbol(
fir: FirAnonymousFunction,
override val token: Invalidatable,
private val builder: KtSymbolByFirBuilder
) : KtAnonymousFunctionSymbol(), KtFirSymbol<FirAnonymousFunction> {
override val fir: FirAnonymousFunction by weakRef(fir)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) }
override val valueParameters: List<KtParameterSymbol> by cached {
fir.valueParameters.map { valueParameter ->
check(valueParameter is FirValueParameterImpl)
builder.buildParameterSymbol(valueParameter)
}
}
}
@@ -0,0 +1,59 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.ReadOnlyWeakRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
internal class KtFirClassOrObjectSymbol(
fir: FirRegularClass,
override val token: Invalidatable,
private val builder: KtSymbolByFirBuilder
) : KtClassOrObjectSymbol(), KtFirSymbol<FirRegularClass> {
override val fir: FirRegularClass by ReadOnlyWeakRef(fir, this)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val name: Name get() = withValidityAssertion { fir.classId.shortClassName }
override val classId: ClassId get() = withValidityAssertion { fir.classId }
override val typeParameters by cached {
fir.typeParameters.map { typeParameter ->
builder.buildTypeParameterSymbol(typeParameter.symbol.fir)
}
}
override val classKind: KtClassKind
get() = withValidityAssertion {
when (fir.classKind) {
ClassKind.INTERFACE -> KtClassKind.INTERFACE
ClassKind.ENUM_CLASS -> KtClassKind.ENUM_CLASS
ClassKind.ENUM_ENTRY -> KtClassKind.ENUM_ENTRY
ClassKind.ANNOTATION_CLASS -> KtClassKind.ANNOTATION_CLASS
ClassKind.CLASS -> if (fir.modality == Modality.ABSTRACT) KtClassKind.ABSTRACT_CLASS else KtClassKind.CLASS
ClassKind.OBJECT -> if (fir.isCompanion) KtClassKind.COMPANION_OBJECT else KtClassKind.OBJECT
}
}
override val symbolKind: KtSymbolKind
get() = withValidityAssertion {
when {
fir.isLocal -> KtSymbolKind.LOCAL
fir.symbol.classId.isNestedClass -> KtSymbolKind.MEMBER
else -> KtSymbolKind.TOP_LEVEL
}
}
}
@@ -0,0 +1,53 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
internal class KtFirConstructorSymbol(
fir: FirConstructor,
override val token: Invalidatable,
private val builder: KtSymbolByFirBuilder
) : KtConstructorSymbol(), KtFirSymbol<FirConstructor> {
override val fir: FirConstructor by weakRef(fir)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) }
override val valueParameters: List<KtConstructorParameterSymbol> by cached {
fir.valueParameters.map { valueParameter ->
check(valueParameter is FirValueParameterImpl)
builder.buildFirConstructorParameter(valueParameter)
}
}
override val isPrimary: Boolean get() = withValidityAssertion { fir.isPrimary }
override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
override val owner: KtClassOrObjectSymbol by cached {
val session = fir.session
val classId = fir.symbol.callableId.classId ?: error("ClassID should present for constructor")
val firClass = session.firSymbolProvider.getClassLikeSymbolByFqName(classId)?.fir
?: error("Class with id $classId id was not found")
check(firClass is FirRegularClass) { "Owner class for constructor should be FirRegularClass, but ${firClass::class} was met" }
builder.buildClassSymbol(firClass)
}
}
@@ -0,0 +1,45 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
internal class KtFirConstructorValueParameterSymbol(
fir: FirValueParameterImpl,
override val token: Invalidatable
) : KtConstructorParameterSymbol(), KtFirSymbol<FirValueParameterImpl> {
override val fir: FirValueParameterImpl by weakRef(fir)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val name: Name get() = withValidityAssertion { fir.name }
override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) }
override val symbolKind: KtSymbolKind
get() = withValidityAssertion {
when {
fir.isVal || fir.isVal -> KtSymbolKind.MEMBER
else -> KtSymbolKind.LOCAL
}
}
override val constructorParameterKind: KtConstructorParameterSymbolKind
get() = withValidityAssertion {
when {
fir.isVal -> KtConstructorParameterSymbolKind.VAL_PROPERTY
fir.isVar -> KtConstructorParameterSymbolKind.VAR_PROPERTY
else -> KtConstructorParameterSymbolKind.NON_PROPERTY
}
}
}
@@ -0,0 +1,32 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtEnumEntrySymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
internal class KtFirEnumEntrySymbol(
fir: FirEnumEntry,
override val token: Invalidatable
) : KtEnumEntrySymbol(), KtFirSymbol<FirEnumEntry> {
override val fir: FirEnumEntry by weakRef(fir)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val name: Name get() = withValidityAssertion { fir.name }
override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) }
}
@@ -0,0 +1,35 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirField
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFieldSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
internal class KtFirFieldSymbol(
fir: FirField,
override val token: Invalidatable
) : KtFieldSymbol(), KtFirSymbol<FirField> {
override val fir: FirField by weakRef(fir)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) }
override val isVal: Boolean get() = withValidityAssertion { fir.isVal }
override val name: Name get() = withValidityAssertion { fir.name }
}
@@ -0,0 +1,60 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.declarations.isLocal
import org.jetbrains.kotlin.fir.declarations.isOperator
import org.jetbrains.kotlin.fir.declarations.isSuspend
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
internal class KtFirFunctionSymbol(
fir: FirSimpleFunction,
override val token: Invalidatable,
private val builder: KtSymbolByFirBuilder,
) : KtFunctionSymbol(), KtFirSymbol<FirSimpleFunction> {
override val fir: FirSimpleFunction by weakRef(fir)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val name: Name get() = withValidityAssertion { fir.name }
override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) }
override val valueParameters: List<KtFirFunctionValueParameterSymbol> by cached {
fir.valueParameters.map { valueParameter ->
check(valueParameter is FirValueParameterImpl)
builder.buildParameterSymbol(valueParameter)
}
}
override val typeParameters by cached {
fir.typeParameters.map { typeParameter ->
builder.buildTypeParameterSymbol(typeParameter.symbol.fir)
}
}
override val isSuspend: Boolean get() = withValidityAssertion { fir.isSuspend }
override val receiverType: TypeInfo? by cached { fir.receiverTypeRef?.asTypeInfo(fir.session, token) }
override val isOperator: Boolean get() = withValidityAssertion { fir.isOperator }
override val isExtension: Boolean get() = withValidityAssertion { fir.receiverTypeRef != null }
override val fqName: FqName? get() = withValidityAssertion { fir.symbol.callableId.asFqNameForDebugInfo() }
override val symbolKind: KtSymbolKind
get() = withValidityAssertion {
when {
fir.isLocal -> KtSymbolKind.LOCAL
fir.symbol.callableId.classId == null -> KtSymbolKind.TOP_LEVEL
else -> KtSymbolKind.MEMBER
}
}
}
@@ -0,0 +1,34 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSimpleFunctionParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
internal class KtFirFunctionValueParameterSymbol(
fir: FirValueParameterImpl,
override val token: Invalidatable
) : KtSimpleFunctionParameterSymbol(),
KtFirSymbol<FirValueParameterImpl> {
override val fir: FirValueParameterImpl by weakRef(fir)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val name: Name get() = withValidityAssertion { fir.name }
override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) }
override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
}
@@ -0,0 +1,37 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
internal class KtFirLocalVariableSymbol(
fir: FirProperty,
override val token: Invalidatable
) : KtLocalVariableSymbol(),
KtFirSymbol<FirProperty> {
init {
assert(fir.isLocal)
}
override val fir: FirProperty by weakRef(fir)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val isVal: Boolean get() = withValidityAssertion { fir.isVal }
override val name: Name get() = withValidityAssertion { fir.name }
override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) }
override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
}
@@ -0,0 +1,46 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
internal class KtFirPropertySymbol(
fir: FirProperty,
override val token: Invalidatable
) : KtPropertySymbol(), KtFirSymbol<FirProperty> {
init {
assert(!fir.isLocal)
}
override val fir: FirProperty by weakRef(fir)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val fqName: FqName get() = withValidityAssertion { fir.symbol.callableId.asFqNameForDebugInfo() }
override val isVal: Boolean get() = withValidityAssertion { fir.isVal }
override val name: Name get() = withValidityAssertion { fir.name }
override val type: TypeInfo by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) }
override val receiverType: TypeInfo? by cached { fir.returnTypeRef.asTypeInfo(fir.session, token) }
override val isExtension: Boolean get() = withValidityAssertion { fir.receiverTypeRef != null }
override val symbolKind: KtSymbolKind
get() = withValidityAssertion {
when (fir.symbol.callableId.classId) {
null -> KtSymbolKind.TOP_LEVEL
else -> KtSymbolKind.MEMBER
}
}
}
@@ -0,0 +1,32 @@
/*
* 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.fir.symbols
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.idea.frontend.api.InvalidatableByValidityToken
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
internal interface KtFirSymbol<F : FirDeclaration> : KtSymbol, InvalidatableByValidityToken {
val fir: F
override val origin: KtSymbolOrigin get() = withValidityAssertion { fir.origin.asKtSymbolOrigin() }
}
private fun FirDeclarationOrigin.asKtSymbolOrigin() = when (this) {
FirDeclarationOrigin.Source -> KtSymbolOrigin.SOURCE
FirDeclarationOrigin.Library -> KtSymbolOrigin.LIBRARY
FirDeclarationOrigin.Java -> KtSymbolOrigin.JAVA
FirDeclarationOrigin.SamConstructor -> KtSymbolOrigin.SAM_CONSTRUCTOR
FirDeclarationOrigin.Synthetic -> throw InvalidFirDeclarationOriginForSymbol(this)
FirDeclarationOrigin.FakeOverride -> throw InvalidFirDeclarationOriginForSymbol(this)
FirDeclarationOrigin.Enhancement -> throw InvalidFirDeclarationOriginForSymbol(this)
is FirDeclarationOrigin.Plugin -> throw InvalidFirDeclarationOriginForSymbol(this)
}
class InvalidFirDeclarationOriginForSymbol(origin: FirDeclarationOrigin) :
IllegalStateException("Invalid FirDeclarationOrigin $origin")
@@ -0,0 +1,27 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.ReadOnlyWeakRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeAliasSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
internal class KtFirTypeAliasSymbol(
fir: FirTypeAlias,
override val token: Invalidatable
) : KtTypeAliasSymbol(), KtFirSymbol<FirTypeAlias> {
override val fir: FirTypeAlias by ReadOnlyWeakRef(fir, this)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val name: Name get() = withValidityAssertion { fir.name }
override val classId: ClassId get() = withValidityAssertion { fir.symbol.classId }
}
@@ -0,0 +1,31 @@
/*
* 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.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.asTypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
internal class KtFirTypeParameterSymbol(
fir: FirTypeParameter,
override val token: Invalidatable
) : KtTypeParameterSymbol(), KtFirSymbol<FirTypeParameter> {
override val fir: FirTypeParameter by weakRef(fir)
override val psi: PsiElement? by cached { fir.findPsi(fir.session) }
override val name: Name get() = withValidityAssertion { fir.name }
}
@@ -0,0 +1,25 @@
/*
* 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.fir.utils
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import java.lang.ref.WeakReference
import kotlin.reflect.KProperty
class ReadOnlyWeakRef<V : Any>(value: V, val invalidatable: Invalidatable) {
val weakRef = WeakReference(value)
@Suppress("NOTHING_TO_INLINE")
inline operator fun getValue(thisRef: Any, property: KProperty<*>): V =
weakRef.get() ?: if (invalidatable.isValid()) {
error("Cone type was garbage collected while analysis session is still valid")
} else {
error("Accessing the invalid coneType")
}
}
@Suppress("NOTHING_TO_INLINE")
internal inline fun <V : Any> Invalidatable.weakRef(value: V) = ReadOnlyWeakRef(value, this)
@@ -0,0 +1,34 @@
/*
* 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.fir.utils
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.InvalidatableByValidityToken
import org.jetbrains.kotlin.idea.frontend.api.assertIsValid
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
// all access are considered to be from a single thread
// which should be checked in invalidatable.assertIsValid()
class ValidityAwareCachedValue<T>(
private val invalidatable: Invalidatable,
private val init: () -> T
) : ReadOnlyProperty<Any, T> {
var value: Any? = UNITITIALIZED
@Suppress("UNCHECKED_CAST")
override fun getValue(thisRef: Any, property: KProperty<*>): T {
invalidatable.assertIsValid()
if (value === UNITITIALIZED) {
value = init()
}
return value as T
}
}
internal fun <T> InvalidatableByValidityToken.cached(init: () -> T) = ValidityAwareCachedValue(token, init)
internal object UNITITIALIZED
@@ -0,0 +1,24 @@
/*
* 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.fir.utils
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
import org.jetbrains.kotlin.idea.frontend.api.Invalidatable
import org.jetbrains.kotlin.idea.frontend.api.InvalidatableByValidityToken
import org.jetbrains.kotlin.idea.frontend.api.TypeInfo
import org.jetbrains.kotlin.idea.frontend.api.fir.ConeTypeInfo
internal fun FirTypeRef.asTypeInfo(session: FirSession, invalidatable: Invalidatable): TypeInfo {
val context = ConeTypeCheckerContext(
isErrorTypeEqualsToAnything = true,
isStubTypeEqualsToAnything = true,
session = session
)
return ConeTypeInfo(coneTypeUnsafe(), context, invalidatable)
}
@@ -7,9 +7,13 @@ package org.jetbrains.kotlin.idea.references
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.frontend.api.fir.FirAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.fir.FirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
interface FirKtReference : KtReference { interface FirKtReference : KtReference {
fun getResolvedToPsi(analysisSession: FirAnalysisSession): Collection<PsiElement> fun resolveToSymbols(analysisSession: FirAnalysisSession): Collection<KtSymbol>
fun getResolvedToPsi(analysisSession: FirAnalysisSession): Collection<PsiElement> =
resolveToSymbols(analysisSession).mapNotNull(KtSymbol::psi)
override val resolver get() = KtFirReferenceResolver override val resolver get() = KtFirReferenceResolver
} }