FIR IDE: introduce containingDeclarationProvider for symbols

This commit is contained in:
Ilya Kirillov
2020-08-12 20:38:45 +03:00
parent b5a4e4c409
commit cadf99ca1e
22 changed files with 247 additions and 66 deletions
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.idea.frontend.api.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtAnonymousFunctionSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtAnonymousFunctionSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol 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.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.serialization.deserialization.KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME import org.jetbrains.kotlin.serialization.deserialization.KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME
@@ -61,7 +61,7 @@ internal class FunctionCallHighlightingVisitor(
is KtConstructorSymbol -> Colors.CONSTRUCTOR_CALL is KtConstructorSymbol -> Colors.CONSTRUCTOR_CALL
is KtAnonymousFunctionSymbol -> null is KtAnonymousFunctionSymbol -> null
is KtFunctionSymbol -> when { is KtFunctionSymbol -> when {
function.fqName == KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME -> Colors.KEYWORD function.fqNameIfNonLocal == KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME -> Colors.KEYWORD
function.isExtension -> Colors.EXTENSION_FUNCTION_CALL function.isExtension -> Colors.EXTENSION_FUNCTION_CALL
function.symbolKind == KtSymbolKind.TOP_LEVEL -> Colors.PACKAGE_FUNCTION_CALL function.symbolKind == KtSymbolKind.TOP_LEVEL -> Colors.PACKAGE_FUNCTION_CALL
else -> Colors.FUNCTION_CALL else -> Colors.FUNCTION_CALL
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.psi.*
abstract class KtAnalysisSession(override val token: ValidityToken) : ValidityTokenOwner { abstract class KtAnalysisSession(override val token: ValidityToken) : ValidityTokenOwner {
abstract val symbolProvider: KtSymbolProvider abstract val symbolProvider: KtSymbolProvider
abstract val scopeProvider: KtScopeProvider abstract val scopeProvider: KtScopeProvider
abstract val containingDeclarationProvider: KtSymbolContainingDeclarationProvider
abstract fun getSmartCastedToTypes(expression: KtExpression): Collection<KtType>? abstract fun getSmartCastedToTypes(expression: KtExpression): Collection<KtType>?
@@ -46,8 +46,8 @@ object DebugSymbolRenderer {
is KtType -> value.asStringForDebugging() is KtType -> value.asStringForDebugging()
is KtSymbol -> { is KtSymbol -> {
val symbolTag = when (value) { val symbolTag = when (value) {
is KtClassLikeSymbol -> renderValue(value.classId) is KtClassLikeSymbol -> renderValue(value.classIdIfNonLocal ?: "<local>/${value.name}")
is KtFunctionSymbol -> renderValue(value.fqName) is KtFunctionSymbol -> renderValue(value.fqNameIfNonLocal ?: "<local>/${value.name}")
is KtConstructorSymbol -> "<constructor>" is KtConstructorSymbol -> "<constructor>"
is KtNamedSymbol -> renderValue(value.name) is KtNamedSymbol -> renderValue(value.name)
else -> TODO(value::class.toString()) else -> TODO(value::class.toString())
@@ -5,21 +5,33 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols package org.jetbrains.kotlin.idea.frontend.api.symbols
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
abstract class KtClassLikeSymbol : KtSymbol, KtNamedSymbol, KtSymbolWithKind { abstract class KtClassLikeSymbol : KtSymbol, KtNamedSymbol, KtSymbolWithKind {
abstract val classId: ClassId abstract val classIdIfNonLocal: ClassId?
abstract override fun createPointer(): KtSymbolPointer<KtClassLikeSymbol> abstract override fun createPointer(): KtSymbolPointer<KtClassLikeSymbol>
} }
abstract class KtTypeAliasSymbol : KtClassLikeSymbol() { abstract class KtTypeAliasSymbol : KtClassLikeSymbol() {
abstract override val classIdIfNonLocal: ClassId
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.TOP_LEVEL final override val symbolKind: KtSymbolKind get() = KtSymbolKind.TOP_LEVEL
final override val containingNonLocalClassIdIfMember: ClassId? get() = null
abstract override val containingPackageFqNameIfTopLevel: FqName
abstract override fun createPointer(): KtSymbolPointer<KtTypeAliasSymbol> abstract override fun createPointer(): KtSymbolPointer<KtTypeAliasSymbol>
} }
abstract class KtClassOrObjectSymbol : KtClassLikeSymbol(), KtSymbolWithTypeParameters, KtSymbolWithModality<KtSymbolModality> { abstract class KtClassOrObjectSymbol : KtClassLikeSymbol(),
KtSymbolWithTypeParameters,
KtSymbolWithModality<KtSymbolModality> {
abstract val classKind: KtClassKind abstract val classKind: KtClassKind
abstract override fun createPointer(): KtSymbolPointer<KtClassOrObjectSymbol> abstract override fun createPointer(): KtSymbolPointer<KtClassOrObjectSymbol>
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols package org.jetbrains.kotlin.idea.frontend.api.symbols
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -17,6 +19,8 @@ sealed class KtFunctionLikeSymbol : KtCallableSymbol(), KtTypedSymbol, KtSymbolW
abstract class KtAnonymousFunctionSymbol : KtFunctionLikeSymbol() { abstract class KtAnonymousFunctionSymbol : KtFunctionLikeSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL final override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
final override val containingNonLocalClassIdIfMember: ClassId? get() = null
final override val containingPackageFqNameIfTopLevel: FqName? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtAnonymousFunctionSymbol> abstract override fun createPointer(): KtSymbolPointer<KtAnonymousFunctionSymbol>
} }
@@ -26,10 +30,10 @@ abstract class KtFunctionSymbol : KtFunctionLikeSymbol(),
KtPossibleExtensionSymbol, KtPossibleExtensionSymbol,
KtSymbolWithTypeParameters, KtSymbolWithTypeParameters,
KtSymbolWithModality<KtCommonSymbolModality> { KtSymbolWithModality<KtCommonSymbolModality> {
abstract val fqNameIfNonLocal: FqName?
abstract val isSuspend: Boolean abstract val isSuspend: Boolean
abstract val isOperator: Boolean abstract val isOperator: Boolean
abstract val fqName: FqName?
abstract override val valueParameters: List<KtFunctionParameterSymbol> abstract override val valueParameters: List<KtFunctionParameterSymbol>
@@ -37,10 +41,12 @@ abstract class KtFunctionSymbol : KtFunctionLikeSymbol(),
} }
abstract class KtConstructorSymbol : KtFunctionLikeSymbol() { abstract class KtConstructorSymbol : KtFunctionLikeSymbol() {
abstract override val valueParameters: List<KtConstructorParameterSymbol>
abstract val isPrimary: Boolean abstract val isPrimary: Boolean
abstract val owner: KtClassOrObjectSymbol
abstract val ownerClassId: ClassId abstract override val valueParameters: List<KtConstructorParameterSymbol>
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
final override val containingPackageFqNameIfTopLevel: FqName? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtConstructorSymbol> abstract override fun createPointer(): KtSymbolPointer<KtConstructorSymbol>
} }
@@ -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 org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind
abstract class KtSymbolContainingDeclarationProvider {
/**
* Returns containing declaration for symbol:
* for top-level declarations returns null
* for class members returns containing class
* for local declaration returns declaration it was declared it
*/
abstract fun getContainingDeclaration(symbol: KtSymbolWithKind): KtSymbolWithKind?
}
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols package org.jetbrains.kotlin.idea.frontend.api.symbols
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -13,13 +15,16 @@ abstract class KtVariableLikeSymbol : KtCallableSymbol(), KtTypedSymbol, KtNamed
abstract override fun createPointer(): KtSymbolPointer<KtVariableLikeSymbol> abstract override fun createPointer(): KtSymbolPointer<KtVariableLikeSymbol>
} }
abstract class KtEnumEntrySymbol : KtVariableLikeSymbol() { abstract class KtEnumEntrySymbol : KtVariableLikeSymbol(), KtSymbolWithKind {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
abstract val enumClassId: ClassId final override val containingPackageFqNameIfTopLevel: FqName? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol> abstract override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol>
} }
abstract class KtParameterSymbol : KtVariableLikeSymbol() { abstract class KtParameterSymbol : KtVariableLikeSymbol() {
final override val containingPackageFqNameIfTopLevel: FqName? get() = null
abstract val hasDefaultValue: Boolean abstract val hasDefaultValue: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtParameterSymbol> abstract override fun createPointer(): KtSymbolPointer<KtParameterSymbol>
@@ -30,28 +35,41 @@ abstract class KtVariableSymbol : KtVariableLikeSymbol() {
abstract override fun createPointer(): KtSymbolPointer<KtVariableSymbol> abstract override fun createPointer(): KtSymbolPointer<KtVariableSymbol>
} }
abstract class KtJavaFieldSymbol : KtVariableSymbol(), KtSymbolWithModality<KtCommonSymbolModality> { abstract class KtJavaFieldSymbol : KtVariableSymbol(), KtSymbolWithModality<KtCommonSymbolModality>, KtSymbolWithKind {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
final override val containingPackageFqNameIfTopLevel: FqName? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtJavaFieldSymbol> abstract override fun createPointer(): KtSymbolPointer<KtJavaFieldSymbol>
} }
// TODO getters & setters // TODO getters & setters
abstract class KtPropertySymbol : KtVariableSymbol(), KtPossibleExtensionSymbol, KtSymbolWithModality<KtCommonSymbolModality> { abstract class KtPropertySymbol : KtVariableSymbol(),
abstract val fqName: FqName KtPossibleExtensionSymbol,
KtSymbolWithModality<KtCommonSymbolModality>,
KtSymbolWithKind {
abstract override fun createPointer(): KtSymbolPointer<KtPropertySymbol> abstract override fun createPointer(): KtSymbolPointer<KtPropertySymbol>
} }
abstract class KtLocalVariableSymbol : KtVariableSymbol() { abstract class KtLocalVariableSymbol : KtVariableSymbol(), KtSymbolWithKind {
final override val containingPackageFqNameIfTopLevel: FqName? get() = null
final override val containingNonLocalClassIdIfMember: ClassId? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtLocalVariableSymbol> abstract override fun createPointer(): KtSymbolPointer<KtLocalVariableSymbol>
} }
abstract class KtFunctionParameterSymbol : KtParameterSymbol() { abstract class KtFunctionParameterSymbol : KtParameterSymbol(), KtSymbolWithKind {
abstract val isVararg: Boolean abstract val isVararg: Boolean
override val symbolKind: KtSymbolKind get() = KtSymbolKind.NON_PROPERTY_PARAMETER
override val containingNonLocalClassIdIfMember: ClassId? get() = null
abstract override fun createPointer(): KtSymbolPointer<KtFunctionParameterSymbol> abstract override fun createPointer(): KtSymbolPointer<KtFunctionParameterSymbol>
} }
abstract class KtConstructorParameterSymbol : KtParameterSymbol(), KtNamedSymbol { abstract class KtConstructorParameterSymbol : KtParameterSymbol(), KtNamedSymbol, KtSymbolWithKind {
abstract val constructorParameterKind: KtConstructorParameterSymbolKind abstract val constructorParameterKind: KtConstructorParameterSymbolKind
abstract override fun createPointer(): KtSymbolPointer<KtConstructorParameterSymbol> abstract override fun createPointer(): KtSymbolPointer<KtConstructorParameterSymbol>
} }
@@ -12,14 +12,6 @@ interface KtNamedSymbol : KtSymbol {
val name: Name val name: Name
} }
interface KtSymbolWithKind : KtSymbol {
val symbolKind: KtSymbolKind
}
enum class KtSymbolKind {
TOP_LEVEL, MEMBER, LOCAL
}
interface KtTypedSymbol : KtSymbol { interface KtTypedSymbol : KtSymbol {
val type: KtType val type: KtType
} }
@@ -0,0 +1,33 @@
/*
* 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.markers
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
/**
* [KtSymbol] which can possibly be class member, top level or local declaration
* Contracts:
* [containingNonLocalClassIdIfMember] != null iff [symbolKind] == [KtSymbolKind.MEMBER]
* [containingPackageFqNameIfTopLevel] != null iff [symbolKind] == [KtSymbolKind.TOP_LEVEL]
*/
interface KtSymbolWithKind : KtSymbol {
val symbolKind: KtSymbolKind
val containingNonLocalClassIdIfMember: ClassId?
val containingPackageFqNameIfTopLevel: FqName?
}
enum class KtSymbolKind {
TOP_LEVEL, MEMBER, LOCAL, NON_PROPERTY_PARAMETER
}
val KtSymbol.containingClassIdIfMember: ClassId?
get() = (this as? KtSymbolWithKind)?.containingClassIdIfMember
val KtSymbol.containingPackageFqNameIfTopLevel: FqName?
get() = (this as? KtSymbolWithKind)?.containingPackageFqNameIfTopLevel
@@ -25,13 +25,11 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade
import org.jetbrains.kotlin.idea.frontend.api.* import org.jetbrains.kotlin.idea.frontend.api.*
import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.KtFirScopeProvider import org.jetbrains.kotlin.idea.frontend.api.fir.scopes.KtFirScopeProvider
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbolContainingDeclarationProvider
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbolProvider import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbolProvider
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.* import org.jetbrains.kotlin.idea.frontend.api.fir.utils.*
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeProvider import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeProvider
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolProvider
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableLikeSymbol
import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper
import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper.toTargetSymbol import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper.toTargetSymbol
@@ -63,6 +61,9 @@ private constructor(
KtFirScopeProvider(token, firSymbolBuilder, project, firResolveState, firScopeStorage) KtFirScopeProvider(token, firSymbolBuilder, project, firResolveState, firScopeStorage)
} }
override val containingDeclarationProvider: KtSymbolContainingDeclarationProvider =
KtFirSymbolContainingDeclarationProvider(this)
init { init {
assertIsValid() assertIsValid()
} }
@@ -15,10 +15,12 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirClassOrObjectInLibrarySymbol import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirClassOrObjectInLibrarySymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.* import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
internal class KtFirClassOrObjectSymbol( internal class KtFirClassOrObjectSymbol(
@@ -30,10 +32,12 @@ internal class KtFirClassOrObjectSymbol(
override val firRef = firRef(fir, resolveState) override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) } override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
override val name: Name get() = firRef.withFir { it.symbol.classId.shortClassName } override val name: Name get() = firRef.withFir { it.symbol.classId.shortClassName }
override val classId: ClassId get() = firRef.withFir { it.symbol.classId } override val classIdIfNonLocal: ClassId?
get() = firRef.withFir { fir ->
fir.symbol.classId.takeUnless { it.isLocal }
}
override val modality: KtSymbolModality override val modality: KtSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() }
get() = firRef.withFir { it.modality.getSymbolModality() }
override val typeParameters by firRef.withFirAndCache { override val typeParameters by firRef.withFirAndCache {
fir.typeParameters.map { typeParameter -> fir.typeParameters.map { typeParameter ->
@@ -61,11 +65,21 @@ internal class KtFirClassOrObjectSymbol(
} }
} }
override val containingNonLocalClassIdIfMember: ClassId?
get() = firRef.withFir { fir ->
fir.classId.outerClassId?.takeUnless { it.isLocal }
}
override val containingPackageFqNameIfTopLevel: FqName?
get() = firRef.withFir { fir ->
fir.classId.packageFqName.takeIf { fir.classId.outerClassId == null }
}
override fun createPointer(): KtSymbolPointer<KtClassOrObjectSymbol> { override fun createPointer(): KtSymbolPointer<KtClassOrObjectSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
if (symbolKind == KtSymbolKind.LOCAL) { if (symbolKind == KtSymbolKind.LOCAL) {
throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(classId.asString()) throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(classIdIfNonLocal?.asString().orEmpty())
} }
return KtFirClassOrObjectInLibrarySymbol(classId) return KtFirClassOrObjectInLibrarySymbol(classIdIfNonLocal!!)
} }
} }
@@ -7,10 +7,8 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl 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.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
@@ -20,6 +18,7 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirConstruc
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignature import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignature
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.* import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
@@ -44,27 +43,19 @@ internal class KtFirConstructorSymbol(
} }
override val isPrimary: Boolean get() = firRef.withFir { it.isPrimary } override val isPrimary: Boolean get() = firRef.withFir { it.isPrimary }
override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
override val ownerClassId: ClassId override val containingNonLocalClassIdIfMember: ClassId?
get() = firRef.withFir { get() = firRef.withFir { fir ->
it.symbol.callableId.classId ?: error("ClassID should present for constructor") fir.symbol.callableId.classId?.takeUnless { it.isLocal }
} }
override val owner: KtClassOrObjectSymbol by firRef.withFirAndCache { fir ->
val session = fir.session
val classId = ownerClassId
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)
}
override fun createPointer(): KtSymbolPointer<KtConstructorSymbol> = withValidityAssertion { override fun createPointer(): KtSymbolPointer<KtConstructorSymbol> = withValidityAssertion {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
if (symbolKind == KtSymbolKind.LOCAL) { if (symbolKind == KtSymbolKind.LOCAL) {
throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException("${ownerClassId.asString()}.constructor") throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException("constructor")
} }
val ownerClassId = containingNonLocalClassIdIfMember
?: error("ClassId should present for member declaration")
return KtFirConstructorSymbolPointer(ownerClassId, isPrimary, firRef.withFir { it.createSignature() }) return KtFirConstructorSymbolPointer(ownerClassId, isPrimary, firRef.withFir { it.createSignature() })
} }
} }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.symbols package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.idea.fir.findPsi import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
@@ -14,8 +15,10 @@ import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.* import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
internal class KtFirConstructorValueParameterSymbol( internal class KtFirConstructorValueParameterSymbol(
@@ -28,14 +31,20 @@ internal class KtFirConstructorValueParameterSymbol(
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) } override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
override val name: Name get() = firRef.withFir { it.name } override val name: Name get() = firRef.withFir { it.name }
override val type: KtType by firRef.withFirAndCache { builder.buildKtType(it.returnTypeRef) } override val type: KtType by firRef.withFirAndCache(FirResolvePhase.TYPES) { builder.buildKtType(it.returnTypeRef) }
override val symbolKind: KtSymbolKind override val symbolKind: KtSymbolKind
get() = firRef.withFir { fir -> get() = firRef.withFir { fir ->
when { when {
fir.isVal || fir.isVal -> KtSymbolKind.MEMBER fir.isVal || fir.isVal -> KtSymbolKind.MEMBER
else -> KtSymbolKind.LOCAL else -> KtSymbolKind.NON_PROPERTY_PARAMETER
} }
} }
override val containingNonLocalClassIdIfMember: ClassId?
get() = firRef.withFir { fir ->
fir.symbol.callableId.classId.takeIf { fir.isVal || fir.isVar }
}
override val constructorParameterKind: KtConstructorParameterSymbolKind override val constructorParameterKind: KtConstructorParameterSymbolKind
get() = firRef.withFir { fir -> get() = firRef.withFir { fir ->
when { when {
@@ -33,10 +33,12 @@ internal class KtFirEnumEntrySymbol(
override val name: Name get() = firRef.withFir { it.name } override val name: Name get() = firRef.withFir { it.name }
override val type: KtType by firRef.withFirAndCache(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { fir -> builder.buildKtType(fir.returnTypeRef) } override val type: KtType by firRef.withFirAndCache(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { fir -> builder.buildKtType(fir.returnTypeRef) }
override val enumClassId: ClassId = firRef.withFir { it.symbol.callableId.classId ?: error("ClassId should present for enum") }
override val containingNonLocalClassIdIfMember: ClassId?
get() = firRef.withFir { it.symbol.callableId.classId?.takeUnless { it.isLocal } }
override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol> { override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
return KtFirEnumEntrySymbolPointer(enumClassId, firRef.withFir { it.createSignature() }) return KtFirEnumEntrySymbolPointer(containingNonLocalClassIdIfMember!!, firRef.withFir { it.createSignature() })
} }
} }
@@ -17,9 +17,11 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirMemberFu
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignature import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignature
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.* import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -49,7 +51,10 @@ internal class KtFirFunctionSymbol(
override val receiverType: KtType? by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> fir.receiverTypeRef?.let(builder::buildKtType) } override val receiverType: KtType? by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> fir.receiverTypeRef?.let(builder::buildKtType) }
override val isOperator: Boolean get() = firRef.withFir { it.isOperator } override val isOperator: Boolean get() = firRef.withFir { it.isOperator }
override val isExtension: Boolean get() = firRef.withFir { it.receiverTypeRef != null } override val isExtension: Boolean get() = firRef.withFir { it.receiverTypeRef != null }
override val fqName: FqName? get() = firRef.withFir { it.symbol.callableId.asFqNameForDebugInfo() } override val fqNameIfNonLocal: FqName?
get() = firRef.withFir { fir ->
fir.symbol.callableId.takeUnless { fir.isLocal }?.asFqNameForDebugInfo()
}
override val symbolKind: KtSymbolKind override val symbolKind: KtSymbolKind
get() = firRef.withFir { fir -> get() = firRef.withFir { fir ->
when { when {
@@ -60,6 +65,16 @@ internal class KtFirFunctionSymbol(
} }
override val modality: KtCommonSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() } override val modality: KtCommonSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() }
override val containingNonLocalClassIdIfMember: ClassId?
get() = firRef.withFir { fir ->
fir.symbol.callableId.classId?.takeUnless { it.isLocal }
}
override val containingPackageFqNameIfTopLevel: FqName?
get() = firRef.withFir { fir ->
fir.symbol.callableId.takeIf { !fir.isLocal && it.className == null }?.packageName
}
override fun createPointer(): KtSymbolPointer<KtFunctionSymbol> { override fun createPointer(): KtSymbolPointer<KtFunctionSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
return when (symbolKind) { return when (symbolKind) {
@@ -68,7 +83,10 @@ internal class KtFirFunctionSymbol(
firRef.withFir { it.symbol.callableId.classId ?: error("ClassId should not be null for member function") }, firRef.withFir { it.symbol.callableId.classId ?: error("ClassId should not be null for member function") },
firRef.withFir { it.createSignature() } firRef.withFir { it.createSignature() }
) )
KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(fqName?.asString() ?: name.asString()) KtSymbolKind.NON_PROPERTY_PARAMETER -> error("KtFunction could not be a parameter")
KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(
fqNameIfNonLocal?.asString() ?: name.asString()
)
} }
} }
} }
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionParameterSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -32,7 +31,6 @@ internal class KtFirFunctionValueParameterSymbol(
override val name: Name get() = firRef.withFir { it.name } override val name: Name get() = firRef.withFir { it.name }
override val isVararg: Boolean get() = firRef.withFir { it.isVararg } override val isVararg: Boolean get() = firRef.withFir { it.isVararg }
override val type: KtType by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> builder.buildKtType(fir.returnTypeRef) } override val type: KtType by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> builder.buildKtType(fir.returnTypeRef) }
override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
override val hasDefaultValue: Boolean get() = firRef.withFir { it.defaultValue != null } override val hasDefaultValue: Boolean get() = firRef.withFir { it.defaultValue != null }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtJavaFieldSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtJavaFieldSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
internal class KtFirJavaFieldSymbol( internal class KtFirJavaFieldSymbol(
@@ -37,6 +38,12 @@ internal class KtFirJavaFieldSymbol(
override val isVal: Boolean get() = firRef.withFir { it.isVal } override val isVal: Boolean get() = firRef.withFir { it.isVal }
override val name: Name get() = firRef.withFir { it.name } override val name: Name get() = firRef.withFir { it.name }
override val containingNonLocalClassIdIfMember: ClassId?
get() = firRef.withFir { fir ->
val classId = fir.symbol.callableId.classId
classId?.takeUnless { it.isLocal }
}
override val modality: KtCommonSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() } override val modality: KtCommonSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() }
override fun createPointer(): KtSymbolPointer<KtJavaFieldSymbol> { override fun createPointer(): KtSymbolPointer<KtJavaFieldSymbol> {
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol 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.markers.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
@@ -19,10 +19,11 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignatu
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol 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.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -39,8 +40,6 @@ internal class KtFirPropertySymbol(
override val firRef = firRef(fir, resolveState) override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) } override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
override val fqName: FqName get() = firRef.withFir { it.symbol.callableId.asFqNameForDebugInfo() }
override val isVal: Boolean get() = firRef.withFir { it.isVal } override val isVal: Boolean get() = firRef.withFir { it.isVal }
override val name: Name get() = firRef.withFir { it.name } override val name: Name get() = firRef.withFir { it.name }
override val type: KtType by firRef.withFirAndCache(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { fir -> builder.buildKtType(fir.returnTypeRef) } override val type: KtType by firRef.withFirAndCache(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { fir -> builder.buildKtType(fir.returnTypeRef) }
@@ -55,15 +54,26 @@ internal class KtFirPropertySymbol(
} }
override val modality: KtCommonSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() } override val modality: KtCommonSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() }
override val containingNonLocalClassIdIfMember: ClassId?
get() = firRef.withFir { fir ->
fir.symbol.callableId.classId
}
override val containingPackageFqNameIfTopLevel: FqName?
get() = firRef.withFir { fir ->
fir.symbol.callableId.packageName.takeIf { fir.symbol.callableId.className == null }
}
override fun createPointer(): KtSymbolPointer<KtPropertySymbol> { override fun createPointer(): KtSymbolPointer<KtPropertySymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
return when (symbolKind) { return when (symbolKind) {
KtSymbolKind.TOP_LEVEL -> TODO("Creating symbol for top level fun is not supported yet") KtSymbolKind.TOP_LEVEL -> TODO("Creating symbol for top level fun is not supported yet")
KtSymbolKind.NON_PROPERTY_PARAMETER -> TODO("Creating symbol for top level parameters is not supported yet")
KtSymbolKind.MEMBER -> KtFirMemberPropertySymbolPointer( KtSymbolKind.MEMBER -> KtFirMemberPropertySymbolPointer(
firRef.withFir { it.symbol.callableId.classId ?: error("ClassId should not be null for member property") }, firRef.withFir { it.symbol.callableId.classId ?: error("ClassId should not be null for member property") },
firRef.withFir { it.createSignature() } firRef.withFir { it.createSignature() }
) )
KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(fqName.asString()) KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(name.asString())
} }
} }
} }
@@ -0,0 +1,49 @@
/*
* 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.util.parentOfType
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithKind
import org.jetbrains.kotlin.psi.KtDeclaration
class KtFirSymbolContainingDeclarationProvider(
private val analysisSession: KtAnalysisSession
) : KtSymbolContainingDeclarationProvider() {
override fun getContainingDeclaration(symbol: KtSymbolWithKind): KtSymbolWithKind? {
if (symbol is KtPackageSymbol) return null
if (symbol.symbolKind == KtSymbolKind.TOP_LEVEL) return null
return when (symbol.origin) {
KtSymbolOrigin.SOURCE -> getContainingDeclarationForKotlinInSourceSymbol(symbol)
KtSymbolOrigin.LIBRARY -> getContainingDeclarationForLibrarySymbol(symbol)
KtSymbolOrigin.JAVA -> TODO()
KtSymbolOrigin.SAM_CONSTRUCTOR -> TODO()
}
}
private fun getContainingDeclarationForKotlinInSourceSymbol(symbol: KtSymbolWithKind): KtSymbolWithKind {
require(symbol.origin == KtSymbolOrigin.SOURCE)
val psi = symbol.psi ?: error("PSI should present for declaration built by Kotlin code")
check(psi is KtDeclaration) { "PSI of kotlin declaration should be KtDeclaration" }
val containingDeclaration = psi.parentOfType<KtDeclaration>()
?: error("Containing declaration should present for non-toplevel declaration")
return with(analysisSession) {
val containingSymbol = symbolProvider.getSymbol(containingDeclaration)
check(containingSymbol is KtSymbolWithKind)
containingSymbol
}
}
private fun getContainingDeclarationForLibrarySymbol(symbol: KtSymbolWithKind): KtSymbolWithKind {
require(symbol.origin == KtSymbolOrigin.LIBRARY)
check(symbol.symbolKind == KtSymbolKind.MEMBER)
val containingClassId = symbol.containingNonLocalClassIdIfMember ?: error("containingClassId should not be null for member declaration")
val containingClass = analysisSession.symbolProvider.getClassOrObjectSymbolByClassId(containingClassId)
return containingClass ?: error("Class with id $containingClassId should exists")
}
}
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeAliasSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
internal class KtFirTypeAliasSymbol( internal class KtFirTypeAliasSymbol(
@@ -25,7 +26,8 @@ internal class KtFirTypeAliasSymbol(
override val firRef = firRef(fir, resolveState) override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) } override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
override val name: Name get() = firRef.withFir { it.name } override val name: Name get() = firRef.withFir { it.name }
override val classId: ClassId get() = firRef.withFir { it.symbol.classId } override val classIdIfNonLocal: ClassId get() = firRef.withFir { it.symbol.classId }
override val containingPackageFqNameIfTopLevel: FqName get() = firRef.withFir { it.symbol.classId.packageFqName }
override fun createPointer(): KtSymbolPointer<KtTypeAliasSymbol> { override fun createPointer(): KtSymbolPointer<KtTypeAliasSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
@@ -90,7 +90,7 @@ private fun CallInfo.stringRepresentation(): String {
fun KtType.render() = asStringForDebugging().replace('/', '.') fun KtType.render() = asStringForDebugging().replace('/', '.')
fun Any.stringValue(): String? = when (this) { fun Any.stringValue(): String? = when (this) {
is KtFunctionLikeSymbol -> buildString { is KtFunctionLikeSymbol -> buildString {
append(if (this@stringValue is KtFunctionSymbol) fqName else "<constructor>") append(if (this@stringValue is KtFunctionSymbol) fqNameIfNonLocal ?: name else "<constructor>")
append("(") append("(")
(this@stringValue as? KtFunctionSymbol)?.receiverType?.let { receiver -> (this@stringValue as? KtFunctionSymbol)?.receiverType?.let { receiver ->
append("<receiver>: ${receiver.render()}") append("<receiver>: ${receiver.render()}")