FIR IDE: separate KtAnnotationApplication and KtAnnotationApplicationValue

This commit is contained in:
Ilya Kirillov
2021-11-23 16:29:04 +01:00
parent b1c8a9e886
commit 47c1da2845
20 changed files with 108 additions and 210 deletions
@@ -5,6 +5,11 @@
package org.jetbrains.kotlin.analysis.api.fir
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.fir.annotations.fullyExpandedClassId
import org.jetbrains.kotlin.analysis.api.fir.annotations.mapAnnotationParameters
import org.jetbrains.kotlin.analysis.api.fir.evaluate.KtFirConstantValueConverter
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
@@ -16,7 +21,12 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtCallElement
import org.jetbrains.kotlin.util.OperatorNameConventions
/**
@@ -63,4 +73,16 @@ internal fun ConeDiagnostic.getCandidateSymbols(): Collection<FirBasedSymbol<*>>
}
is ConeDiagnosticWithCandidates -> candidateSymbols
else -> emptyList()
}
}
internal fun FirAnnotation.toKtAnnotationApplication(useSiteSession: FirSession): KtAnnotationApplication {
return KtAnnotationApplication(
fullyExpandedClassId(useSiteSession),
psi as? KtAnnotationEntry,
useSiteTarget,
KtFirConstantValueConverter.toNamedConstantValue(
mapAnnotationParameters(this, useSiteSession),
useSiteSession,
)
)
}
@@ -1,57 +0,0 @@
/*
* Copyright 2010-2021 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.analysis.api.fir.annotations
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.annotations.KtNamedConstantValue
import org.jetbrains.kotlin.analysis.api.fir.evaluate.KtFirConstantValueConverter
import org.jetbrains.kotlin.analysis.api.fir.utils.FirRefWithValidityCheck
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveType
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtCallElement
internal class KtFirAnnotationApplicationForDeclaration(
private val containingDeclaration: FirRefWithValidityCheck<FirDeclaration>,
private val useSiteSession: FirSession,
private val annotation: FirAnnotation,
override val token: ValidityToken,
) : KtAnnotationApplication() {
override val psi: KtCallElement? by cached { annotation.psi as? KtCallElement }
override val classId: ClassId? by cached {
containingDeclaration.withFirByType(ResolveType.AnnotationType) {
annotation.fullyExpandedClassId(useSiteSession)
}
}
override val useSiteTarget: AnnotationUseSiteTarget? get() = withValidityAssertion { annotation.useSiteTarget }
override val arguments: List<KtNamedConstantValue> by containingDeclaration.withFirAndCache(ResolveType.AnnotationsArguments) {
KtFirConstantValueConverter.toNamedConstantValue(
mapAnnotationParameters(annotation, useSiteSession),
useSiteSession,
)
}
override fun equals(other: Any?): Boolean {
if (other !is KtFirAnnotationApplicationForDeclaration) return false
if (this.token != other.token) return false
return annotation == other.annotation
}
override fun hashCode(): Int {
return token.hashCode() * 31 + annotation.hashCode()
}
}
@@ -1,51 +0,0 @@
/*
* Copyright 2010-2021 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.analysis.api.fir.annotations
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.annotations.KtNamedConstantValue
import org.jetbrains.kotlin.analysis.api.fir.evaluate.KtFirConstantValueConverter
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtCallElement
internal class KtFirAnnotationApplicationImpl(
private val annotation: FirAnnotation,
private val useSiteSession: FirSession,
override val token: ValidityToken,
) : KtAnnotationApplication() {
override val psi: KtCallElement? by cached { annotation.psi as? KtCallElement }
override val classId: ClassId?
get() = withValidityAssertion {
annotation.fullyExpandedClassId(useSiteSession)
}
override val useSiteTarget: AnnotationUseSiteTarget? get() = annotation.useSiteTarget
override val arguments: List<KtNamedConstantValue> by cached {
KtFirConstantValueConverter.toNamedConstantValue(
mapAnnotationParameters(annotation, useSiteSession),
useSiteSession,
)
}
override fun equals(other: Any?): Boolean {
if (other !is KtFirAnnotationApplicationImpl) return false
return annotation == other.annotation
}
override fun hashCode(): Int {
return annotation.hashCode()
}
}
@@ -7,11 +7,13 @@ package org.jetbrains.kotlin.analysis.api.fir.annotations
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.fir.utils.FirRefWithValidityCheck
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveType
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.name.ClassId
internal class KtFirAnnotationListForDeclaration private constructor(
@@ -20,9 +22,9 @@ internal class KtFirAnnotationListForDeclaration private constructor(
override val token: ValidityToken,
) : KtAnnotationsList() {
override val annotations: List<KtAnnotationApplication>
get() = firRef.withFir { fir ->
get() = firRef.withFir(FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS) { fir ->
fir.annotations.map { annotation ->
KtFirAnnotationApplicationForDeclaration(firRef, useSiteSession, annotation, token)
annotation.toKtAnnotationApplication(useSiteSession)
}
}
@@ -33,12 +35,13 @@ internal class KtFirAnnotationListForDeclaration private constructor(
}
}
override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplication> = firRef.withFir { fir ->
fir.annotations.mapNotNull { annotation ->
if (annotation.fullyExpandedClassId(useSiteSession) != classId) return@mapNotNull null
KtFirAnnotationApplicationForDeclaration(firRef, useSiteSession, annotation, token)
override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplication> =
firRef.withFir(FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS) { fir ->
fir.annotations.mapNotNull { annotation ->
if (annotation.fullyExpandedClassId(useSiteSession) != classId) return@mapNotNull null
annotation.toKtAnnotationApplication(useSiteSession)
}
}
}
override val annotationClassIds: Collection<ClassId>
get() = firRef.withFirByType(ResolveType.AnnotationType) { fir ->
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.api.fir.annotations
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
@@ -21,7 +22,7 @@ internal class KtFirAnnotationListForType private constructor(
override val token: ValidityToken,
) : KtAnnotationsList() {
override val annotations: List<KtAnnotationApplication>
get() = withValidityAssertion { coneType.customAnnotations.map { KtFirAnnotationApplicationImpl(it, useSiteSession, token) } }
get() = withValidityAssertion { coneType.customAnnotations.map { it.toKtAnnotationApplication(useSiteSession) } }
override fun containsAnnotation(classId: ClassId): Boolean = withValidityAssertion {
@@ -31,14 +32,13 @@ internal class KtFirAnnotationListForType private constructor(
override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplication> = withValidityAssertion {
coneType.customAnnotations.mapNotNull { annotation ->
if (annotation.fullyExpandedClassId(useSiteSession) != classId) return@mapNotNull null
KtFirAnnotationApplicationImpl(annotation, useSiteSession, token)
annotation.toKtAnnotationApplication(useSiteSession)
}
}
override val annotationClassIds: Collection<ClassId>
get() = withValidityAssertion { coneType.customAnnotations.mapNotNull { it.fullyExpandedClassId(useSiteSession) } }
companion object {
fun create(
coneType: ConeKotlinType,
@@ -25,9 +25,9 @@ internal object KtFirConstantValueConverter {
fun toNamedConstantValue(
argumentMapping: Map<String, FirExpression>,
session: FirSession,
): List<KtNamedConstantValue> =
): List<KtNamedAnnotationValue> =
argumentMapping.map { (name, expression) ->
KtNamedConstantValue(
KtNamedAnnotationValue(
name,
expression.convertConstantExpression(session) ?: KtUnsupportedAnnotationValue
)
@@ -106,10 +106,13 @@ internal object KtFirConstantValueConverter {
argumentMapping?.entries?.forEach { (arg, param) ->
resultMap[param.name.asString()] = arg
}
KtAnnotationAnnotationValue(
resolvedSymbol.callableId.classId,
toNamedConstantValue(resultMap, session),
psi as? KtCallElement
KtAnnotationApplicationValue(
KtAnnotationApplication(
resolvedSymbol.callableId.classId,
psi as? KtAnnotationEntry,
useSiteTarget = null,
toNamedConstantValue(resultMap, session),
)
)
} else null
}
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationApplicationForDeclaration
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration
import org.jetbrains.kotlin.analysis.api.fir.findPsi
import org.jetbrains.kotlin.analysis.api.fir.utils.cached