FIR usage: resolve KtFirSimpleNameReference using getter/setter

`fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement>`
of `KtFirReference` resolves the target of the reference. When the
target of reference to a property is a getter or setter, we have to
check the getter/setter if the target for the property does not
exist. This commit adds the fallback logic i.e., resolving the
getter/setter of the property in
`fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement>`
of `KtFirSimpleNameReference`.
This commit is contained in:
Jaebaek Seo
2022-06-15 16:38:31 +00:00
committed by Ilya Kirillov
parent eb453dc96b
commit 6b3c10fa9c
2 changed files with 31 additions and 7 deletions
@@ -9,10 +9,11 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirNamedClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSyntheticJavaPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.references.ReferenceAccess
internal class KtFirSimpleNameReference(
expression: KtSimpleNameExpression
@@ -43,6 +44,23 @@ internal class KtFirSimpleNameReference(
return fixUpAnnotationCallResolveToCtor(results)
}
override fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement> = with(analysisSession) {
val referenceTargetSymbols = resolveToSymbols()
val psiOfReferenceTarget = super.getResolvedToPsi(analysisSession, referenceTargetSymbols)
if (psiOfReferenceTarget.isNotEmpty()) return psiOfReferenceTarget
referenceTargetSymbols.flatMap { symbol ->
when (symbol) {
is KtFirSyntheticJavaPropertySymbol ->
when (expression.readWriteAccess(useResolveForReadWrite = true)) {
ReferenceAccess.READ -> listOfNotNull(symbol.javaGetterSymbol.psi)
ReferenceAccess.WRITE -> listOfNotNull(symbol.javaSetterSymbol?.psi)
ReferenceAccess.READ_WRITE -> listOfNotNull(symbol.javaGetterSymbol.psi, symbol.javaSetterSymbol?.psi)
}
else -> listOfNotNull(symbol.psi)
}
}
}
override fun canBeReferenceTo(candidateTarget: PsiElement): Boolean {
return true // TODO
}
@@ -15,14 +15,20 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
interface KtFirReference : KtReference, KtSymbolBasedReference {
fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement> = with(analysisSession) {
resolveToSymbols().flatMap { symbol ->
when (symbol) {
is KtFirSymbol<*> -> getPsiDeclarations(symbol)
else -> listOfNotNull(symbol.psi)
fun getResolvedToPsi(analysisSession: KtAnalysisSession, referenceTargetSymbols: Collection<KtSymbol>): Collection<PsiElement> =
with(analysisSession) {
referenceTargetSymbols.flatMap { symbol ->
when (symbol) {
is KtFirSymbol<*> -> getPsiDeclarations(symbol)
else -> listOfNotNull(symbol.psi)
}
}
}
}
fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection<PsiElement> =
with(analysisSession) {
getResolvedToPsi(analysisSession, resolveToSymbols())
}
private fun KtAnalysisSession.getPsiDeclarations(symbol: KtFirSymbol<*>): Collection<PsiElement> {
val intersectionOverriddenSymbolsOrSingle = when {