FIR IDE: introduce property accessor symbols

This commit is contained in:
Ilya Kirillov
2020-08-25 15:34:44 +03:00
parent aae56cadac
commit 30ac80a506
11 changed files with 204 additions and 15 deletions
@@ -94,6 +94,8 @@ abstract class KtAnalysisSession(override val token: ValidityToken) : ValidityTo
fun KtClassOrObject.getClassOrObjectSymbol(): KtClassOrObjectSymbol = symbolProvider.getClassOrObjectSymbol(this)
fun KtPropertyAccessor.getPropertyAccessorSymbol(): KtPropertyAccessorSymbol = symbolProvider.getPropertyAccessorSymbol(this)
/**
* @return symbol with specified [this@getClassOrObjectSymbolByClassId] or `null` in case such symbol is not found
*/
@@ -0,0 +1,28 @@
/*
* 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.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtTypedSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
sealed class KtPropertyAccessorSymbol : KtSymbol,
KtSymbolWithModality<KtCommonSymbolModality> {
abstract val isDefault: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtPropertyAccessorSymbol>
}
abstract class KtPropertyGetterSymbol : KtPropertyAccessorSymbol(), KtTypedSymbol {
abstract override fun createPointer(): KtSymbolPointer<KtPropertyGetterSymbol>
}
abstract class KtPropertySetterSymbol : KtPropertyAccessorSymbol() {
abstract val parameter: KtSetterParameterSymbol
abstract override fun createPointer(): KtSymbolPointer<KtPropertySetterSymbol>
}
@@ -22,6 +22,7 @@ abstract class KtSymbolProvider : KtAnalysisSessionComponent() {
is KtLambdaExpression -> getAnonymousFunctionSymbol(psi)
is KtProperty -> getVariableSymbol(psi)
is KtClassOrObject -> getClassOrObjectSymbol(psi)
is KtPropertyAccessor -> getPropertyAccessorSymbol(psi)
else -> error("Cannot build symbol for ${psi::class}")
}
@@ -35,6 +36,7 @@ abstract class KtSymbolProvider : KtAnalysisSessionComponent() {
abstract fun getAnonymousFunctionSymbol(psi: KtLambdaExpression): KtAnonymousFunctionSymbol
abstract fun getVariableSymbol(psi: KtProperty): KtVariableSymbol
abstract fun getClassOrObjectSymbol(psi: KtClassOrObject): KtClassOrObjectSymbol
abstract fun getPropertyAccessorSymbol(psi: KtPropertyAccessor): KtPropertyAccessorSymbol
/**
* @return symbol with specified [classId] or `null` in case such symbol is not found
@@ -21,11 +21,6 @@ abstract class KtEnumEntrySymbol : KtVariableLikeSymbol(), KtSymbolWithKind {
abstract override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol>
}
sealed class KtParameterSymbol : KtVariableLikeSymbol() {
abstract val hasDefaultValue: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtParameterSymbol>
}
sealed class KtVariableSymbol : KtVariableLikeSymbol() {
abstract val isVal: Boolean
@@ -55,20 +50,32 @@ abstract class KtLocalVariableSymbol : KtVariableSymbol(), KtSymbolWithKind {
abstract override fun createPointer(): KtSymbolPointer<KtLocalVariableSymbol>
}
abstract class KtFunctionParameterSymbol : KtParameterSymbol(), KtSymbolWithKind {
sealed class KtParameterSymbol : KtVariableLikeSymbol(), KtSymbolWithKind {
abstract val hasDefaultValue: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtParameterSymbol>
}
abstract class KtFunctionParameterSymbol : KtParameterSymbol() {
abstract val isVararg: Boolean
override val symbolKind: KtSymbolKind get() = KtSymbolKind.NON_PROPERTY_PARAMETER
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.NON_PROPERTY_PARAMETER
abstract override fun createPointer(): KtSymbolPointer<KtFunctionParameterSymbol>
}
abstract class KtConstructorParameterSymbol : KtParameterSymbol(), KtNamedSymbol, KtSymbolWithKind {
abstract class KtConstructorParameterSymbol : KtParameterSymbol() {
abstract val constructorParameterKind: KtConstructorParameterSymbolKind
abstract override fun createPointer(): KtSymbolPointer<KtConstructorParameterSymbol>
}
abstract class KtSetterParameterSymbol : KtParameterSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.NON_PROPERTY_PARAMETER
abstract override fun createPointer(): KtSymbolPointer<KtSetterParameterSymbol>
}
enum class KtConstructorParameterSymbolKind {
VAL_PROPERTY, VAR_PROPERTY, NON_PROPERTY
}
@@ -92,6 +92,7 @@ internal class KtSymbolByFirBuilder private constructor(
is FirEnumEntry -> buildEnumEntrySymbol(fir)
is FirField -> buildFieldSymbol(fir)
is FirAnonymousFunction -> buildAnonymousFunctionSymbol(fir)
is FirPropertyAccessor -> buildPropertyAccessorSymbol(fir)
else ->
TODO(fir::class.toString())
}
@@ -111,12 +112,15 @@ internal class KtSymbolByFirBuilder private constructor(
// TODO it can be a constructor parameter, which may be split into parameter & property
// we should handle them both
fun buildParameterSymbol(fir: FirValueParameterImpl) =
fun buildParameterSymbol(fir: FirValueParameter) =
symbolsCache.cache(fir) { KtFirFunctionValueParameterSymbol(fir, resolveState, token, this) }
fun buildFirConstructorParameter(fir: FirValueParameterImpl) =
fun buildFirConstructorParameter(fir: FirValueParameter) =
symbolsCache.cache(fir) { KtFirConstructorValueParameterSymbol(fir, resolveState, token, this) }
fun buildFirSetterParameter(fir: FirValueParameter): KtFirSetterParameterSymbol =
symbolsCache.cache(fir) { KtFirSetterParameterSymbol(fir, resolveState, token, this) }
fun buildFunctionSymbol(fir: FirSimpleFunction) = symbolsCache.cache(fir) {
KtFirFunctionSymbol(fir, resolveState, token, this)
}
@@ -137,6 +141,13 @@ internal class KtSymbolByFirBuilder private constructor(
}
}
fun buildPropertyAccessorSymbol(fir: FirPropertyAccessor): KtPropertyAccessorSymbol = symbolsCache.cache(fir) {
when {
fir.isGetter -> KtFirPropertyGetterSymbol(fir, resolveState, token, this)
else -> KtFirPropertySetterSymbol(fir, resolveState, token, this)
}
}
fun buildClassLikeSymbolByLookupTag(lookupTag: ConeClassLikeLookupTag): KtClassLikeSymbol? = withValidityAssertion {
firProvider.getSymbolByLookupTag(lookupTag)?.fir?.let(::buildClassLikeSymbol)
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
@@ -22,11 +23,11 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
internal class KtFirConstructorValueParameterSymbol(
fir: FirValueParameterImpl,
fir: FirValueParameter,
resolveState: FirModuleResolveState,
override val token: ValidityToken,
private val builder: KtSymbolByFirBuilder
) : KtConstructorParameterSymbol(), KtFirSymbol<FirValueParameterImpl> {
) : KtConstructorParameterSymbol(), KtFirSymbol<FirValueParameter> {
override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
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.FirValueParameter
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
@@ -20,11 +20,11 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.Name
internal class KtFirFunctionValueParameterSymbol(
fir: FirValueParameterImpl,
fir: FirValueParameter,
resolveState: FirModuleResolveState,
override val token: ValidityToken,
private val builder: KtSymbolByFirBuilder
) : KtFunctionParameterSymbol(), KtFirSymbol<FirValueParameterImpl> {
) : KtFunctionParameterSymbol(), KtFirSymbol<FirValueParameter> {
override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
@@ -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.FirPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.modality
import org.jetbrains.kotlin.idea.fir.findPsi
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.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertyGetterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtCommonSymbolModality
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.types.KtType
internal class KtFirPropertyGetterSymbol(
fir: FirPropertyAccessor,
resolveState: FirModuleResolveState,
override val token: ValidityToken,
private val builder: KtSymbolByFirBuilder,
) : KtPropertyGetterSymbol(), KtFirSymbol<FirPropertyAccessor> {
init {
require(fir.isGetter)
}
override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
override val isDefault: Boolean get() = firRef.withFir { it is FirDefaultPropertyAccessor }
override val type: KtType = firRef.withFir(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { builder.buildKtType(it.returnTypeRef) }
override val modality: KtCommonSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() }
override fun createPointer(): KtSymbolPointer<KtPropertyGetterSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
TODO("Creating pointers for getters from library is not supported yet")
}
}
@@ -0,0 +1,47 @@
/*
* 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.FirPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.modality
import org.jetbrains.kotlin.idea.fir.findPsi
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.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySetterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSetterParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
internal class KtFirPropertySetterSymbol(
fir: FirPropertyAccessor,
resolveState: FirModuleResolveState,
override val token: ValidityToken,
private val builder: KtSymbolByFirBuilder,
) : KtPropertySetterSymbol(), KtFirSymbol<FirPropertyAccessor> {
init {
require(fir.isSetter)
}
override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
override val isDefault: Boolean get() = firRef.withFir { it is FirDefaultPropertyAccessor }
override val modality: KtCommonSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() }
override val parameter: KtSetterParameterSymbol by firRef.withFirAndCache { fir ->
builder.buildFirSetterParameter(fir.valueParameters.single())
}
override fun createPointer(): KtSymbolPointer<KtPropertySetterSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
TODO("Creating pointers for setters from library is not supported yet")
}
}
@@ -0,0 +1,42 @@
/*
* 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.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.idea.fir.findPsi
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.types.KtType
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.symbols.KtFunctionParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSetterParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.Name
internal class KtFirSetterParameterSymbol(
fir: FirValueParameter,
resolveState: FirModuleResolveState,
override val token: ValidityToken,
private val builder: KtSymbolByFirBuilder
) : KtSetterParameterSymbol(), KtFirSymbol<FirValueParameter> {
override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
override val name: Name get() = firRef.withFir { it.name }
override val type: KtType by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> builder.buildKtType(fir.returnTypeRef) }
override val hasDefaultValue: Boolean get() = firRef.withFir { it.defaultValue != null }
override fun createPointer(): KtSymbolPointer<KtSetterParameterSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
TODO("Creating pointers for functions parameters from library is not supported yet")
}
}
@@ -70,6 +70,10 @@ internal class KtFirSymbolProvider(
firSymbolBuilder.buildClassSymbol(psi.getOrBuildFirOfType(resolveState))
}
override fun getPropertyAccessorSymbol(psi: KtPropertyAccessor): KtPropertyAccessorSymbol = withValidityAssertion {
firSymbolBuilder.buildPropertyAccessorSymbol(psi.getOrBuildFirOfType(resolveState))
}
override fun getClassOrObjectSymbolByClassId(classId: ClassId): KtClassOrObjectSymbol? = withValidityAssertion {
val symbol = firSymbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol ?: return null
firSymbolBuilder.buildClassSymbol(symbol.fir)