diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt index 19c80fb56cd..7628825bcd2 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt @@ -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 */ diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtPropertyAccessorSymbol.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtPropertyAccessorSymbol.kt new file mode 100644 index 00000000000..c8e767fb74a --- /dev/null +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtPropertyAccessorSymbol.kt @@ -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 { + abstract val isDefault: Boolean + + abstract override fun createPointer(): KtSymbolPointer +} + +abstract class KtPropertyGetterSymbol : KtPropertyAccessorSymbol(), KtTypedSymbol { + abstract override fun createPointer(): KtSymbolPointer +} + +abstract class KtPropertySetterSymbol : KtPropertyAccessorSymbol() { + abstract val parameter: KtSetterParameterSymbol + + abstract override fun createPointer(): KtSymbolPointer +} \ No newline at end of file diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtSymbolProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtSymbolProvider.kt index de79da6124e..308f0ea0e87 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtSymbolProvider.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtSymbolProvider.kt @@ -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 diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtVariableLikeSymbol.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtVariableLikeSymbol.kt index 1d157e06df5..33971386ef6 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtVariableLikeSymbol.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/symbols/KtVariableLikeSymbol.kt @@ -21,11 +21,6 @@ abstract class KtEnumEntrySymbol : KtVariableLikeSymbol(), KtSymbolWithKind { abstract override fun createPointer(): KtSymbolPointer } -sealed class KtParameterSymbol : KtVariableLikeSymbol() { - abstract val hasDefaultValue: Boolean - - abstract override fun createPointer(): KtSymbolPointer -} sealed class KtVariableSymbol : KtVariableLikeSymbol() { abstract val isVal: Boolean @@ -55,20 +50,32 @@ abstract class KtLocalVariableSymbol : KtVariableSymbol(), KtSymbolWithKind { abstract override fun createPointer(): KtSymbolPointer } -abstract class KtFunctionParameterSymbol : KtParameterSymbol(), KtSymbolWithKind { +sealed class KtParameterSymbol : KtVariableLikeSymbol(), KtSymbolWithKind { + abstract val hasDefaultValue: Boolean + + abstract override fun createPointer(): KtSymbolPointer +} + +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 } -abstract class KtConstructorParameterSymbol : KtParameterSymbol(), KtNamedSymbol, KtSymbolWithKind { +abstract class KtConstructorParameterSymbol : KtParameterSymbol() { abstract val constructorParameterKind: KtConstructorParameterSymbolKind abstract override fun createPointer(): KtSymbolPointer } +abstract class KtSetterParameterSymbol : KtParameterSymbol() { + final override val symbolKind: KtSymbolKind get() = KtSymbolKind.NON_PROPERTY_PARAMETER + + abstract override fun createPointer(): KtSymbolPointer +} + enum class KtConstructorParameterSymbolKind { VAL_PROPERTY, VAR_PROPERTY, NON_PROPERTY } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt index b6b4c7d4390..6f97fe876b4 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt @@ -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) } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorValueParameterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorValueParameterSymbol.kt index 2f518a4b533..fdef3ac9f71 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorValueParameterSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirConstructorValueParameterSymbol.kt @@ -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 { +) : KtConstructorParameterSymbol(), KtFirSymbol { override val firRef = firRef(fir, resolveState) override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionValueParameterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionValueParameterSymbol.kt index 477e4cfef2f..8b5e9efb3fd 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionValueParameterSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionValueParameterSymbol.kt @@ -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 { +) : KtFunctionParameterSymbol(), KtFirSymbol { override val firRef = firRef(fir, resolveState) override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertyGetterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertyGetterSymbol.kt new file mode 100644 index 00000000000..b57eec4a773 --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertyGetterSymbol.kt @@ -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 { + 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 { + KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } + TODO("Creating pointers for getters from library is not supported yet") + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySetterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySetterSymbol.kt new file mode 100644 index 00000000000..96bc6ccfdfc --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySetterSymbol.kt @@ -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 { + 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 { + KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } + TODO("Creating pointers for setters from library is not supported yet") + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSetterParameterSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSetterParameterSymbol.kt new file mode 100644 index 00000000000..0ca309770b4 --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSetterParameterSymbol.kt @@ -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 { + 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 { + KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it } + TODO("Creating pointers for functions parameters from library is not supported yet") + } +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbolProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbolProvider.kt index 5165f91945b..4d869bac055 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbolProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbolProvider.kt @@ -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)