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
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.api.descriptors.annotations
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.maybeLocalClassId import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.maybeLocalClassId
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
@@ -21,7 +22,7 @@ internal class KtFe10AnnotationsList private constructor(
) : KtAnnotationsList() { ) : KtAnnotationsList() {
override val annotations: List<KtAnnotationApplication> override val annotations: List<KtAnnotationApplication>
get() = withValidityAssertion { get() = withValidityAssertion {
fe10Annotations.map { KtFe10DescAnnotationApplication(it, token) } fe10Annotations.map { it.toKtAnnotationApplication() }
} }
override val annotationClassIds: Collection<ClassId> override val annotationClassIds: Collection<ClassId>
@@ -43,7 +44,7 @@ internal class KtFe10AnnotationsList private constructor(
override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplication> = withValidityAssertion { override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplication> = withValidityAssertion {
fe10Annotations.mapNotNull { annotation -> fe10Annotations.mapNotNull { annotation ->
if (annotation.annotationClass?.maybeLocalClassId != classId) return@mapNotNull null if (annotation.annotationClass?.maybeLocalClassId != classId) return@mapNotNull null
KtFe10DescAnnotationApplication(annotation, token) annotation.toKtAnnotationApplication()
} }
} }
@@ -1,47 +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.descriptors.annotations
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.annotations.KtNamedConstantValue
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.maybeLocalClassId
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtConstantValue
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtCallElement
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
internal class KtFe10DescAnnotationApplication(
private val descriptor: AnnotationDescriptor,
override val token: ValidityToken
) : KtAnnotationApplication() {
override val classId: ClassId?
get() = withValidityAssertion { descriptor.annotationClass?.maybeLocalClassId }
override val useSiteTarget: AnnotationUseSiteTarget?
get() = withValidityAssertion {
val psiTarget = (descriptor as? LazyAnnotationDescriptor)?.annotationEntry?.useSiteTarget ?: return null
return psiTarget.getAnnotationUseSiteTarget()
}
val source: SourceElement
get() = withValidityAssertion { descriptor.source }
override val psi: KtCallElement?
get() = withValidityAssertion { (source as? PsiSourceElement)?.psi as? KtAnnotationEntry }
override val arguments: List<KtNamedConstantValue>
get() = withValidityAssertion {
descriptor.allValueArguments.map { (name, value) -> KtNamedConstantValue(name.asString(), value.toKtConstantValue()) }
}
}
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.descriptors.impl.*
import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
@@ -30,6 +31,7 @@ import org.jetbrains.kotlin.load.kotlin.toSourceElement
import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
@@ -37,7 +39,9 @@ import org.jetbrains.kotlin.resolve.constants.*
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor
import org.jetbrains.kotlin.resolve.sam.SamConstructorDescriptor import org.jetbrains.kotlin.resolve.sam.SamConstructorDescriptor
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
@@ -281,8 +285,15 @@ internal fun ConstantValue<*>.toKtConstantValue(): KtAnnotationValue {
is ArrayValue -> KtArrayAnnotationValue(value.map { it.toKtConstantValue() }, null) is ArrayValue -> KtArrayAnnotationValue(value.map { it.toKtConstantValue() }, null)
is EnumValue -> KtEnumEntryAnnotationValue(CallableId(enumClassId, enumEntryName), null) is EnumValue -> KtEnumEntryAnnotationValue(CallableId(enumClassId, enumEntryName), null)
is AnnotationValue -> { is AnnotationValue -> {
val arguments = value.allValueArguments.map { (name, v) -> KtNamedConstantValue(name.asString(), v.toKtConstantValue()) } val arguments = value.allValueArguments.map { (name, v) -> KtNamedAnnotationValue(name.asString(), v.toKtConstantValue()) }
KtAnnotationAnnotationValue(value.annotationClass?.classId, arguments, null) KtAnnotationApplicationValue(
KtAnnotationApplication(
value.annotationClass?.classId,
psi = null,
useSiteTarget = null,
arguments = arguments
)
)
} }
is ErrorValue -> KtErrorValue(this.toString()) is ErrorValue -> KtErrorValue(this.toString())
else -> KtUnsupportedAnnotationValue else -> KtUnsupportedAnnotationValue
@@ -418,4 +429,13 @@ internal fun createKtInitializerValue(
} }
return KtNonConstantInitializerValue(initializer) return KtNonConstantInitializerValue(initializer)
}
internal fun AnnotationDescriptor.toKtAnnotationApplication(): KtAnnotationApplication {
return KtAnnotationApplication(
annotationClass?.maybeLocalClassId,
(source as? PsiSourceElement)?.psi as? KtAnnotationEntry,
(this as? LazyAnnotationDescriptor)?.annotationEntry?.useSiteTarget?.getAnnotationUseSiteTarget(),
allValueArguments.map { (name, value) -> KtNamedAnnotationValue(name.asString(), value.toKtConstantValue()) }
)
} }
@@ -88,11 +88,11 @@ internal class KtFe10TypeRenderer(private val options: KtTypeRendererOptions, pr
} }
private fun KtFe10RendererConsumer.renderTypeAnnotationDebug(annotation: AnnotationDescriptor) { private fun KtFe10RendererConsumer.renderTypeAnnotationDebug(annotation: AnnotationDescriptor) {
val namedValues = annotation.allValueArguments.map { KtNamedConstantValue(it.key.asString(), it.value.toKtConstantValue()) } val namedValues = annotation.allValueArguments.map { KtNamedAnnotationValue(it.key.asString(), it.value.toKtConstantValue()) }
renderAnnotationDebug(annotation.annotationClass?.classId, namedValues) renderAnnotationDebug(annotation.annotationClass?.classId, namedValues)
} }
private fun KtFe10RendererConsumer.renderAnnotationDebug(classId: ClassId?, namedValues: List<KtNamedConstantValue>) { private fun KtFe10RendererConsumer.renderAnnotationDebug(classId: ClassId?, namedValues: List<KtNamedAnnotationValue>) {
append("@") append("@")
if (classId != null) { if (classId != null) {
@@ -111,7 +111,7 @@ internal class KtFe10TypeRenderer(private val options: KtTypeRendererOptions, pr
private fun KtFe10RendererConsumer.renderConstantValueDebug(value: KtAnnotationValue) { private fun KtFe10RendererConsumer.renderConstantValueDebug(value: KtAnnotationValue) {
when (value) { when (value) {
is KtAnnotationAnnotationValue -> renderAnnotationDebug(value.classId, value.arguments) is KtAnnotationApplicationValue -> renderAnnotationDebug(value.annotationValue.classId, value.annotationValue.arguments)
is KtArrayAnnotationValue -> is KtArrayAnnotationValue ->
renderList(value.values, separator = ", ", prefix = "[", postfix = "]") { renderConstantValueDebug(it) } renderList(value.values, separator = ", ", prefix = "[", postfix = "]") { renderConstantValueDebug(it) }
is KtEnumEntryAnnotationValue -> append(value.callableId) is KtEnumEntryAnnotationValue -> append(value.callableId)
@@ -5,6 +5,11 @@
package org.jetbrains.kotlin.analysis.api.fir 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.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression 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.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol 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.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 import org.jetbrains.kotlin.util.OperatorNameConventions
/** /**
@@ -63,4 +73,16 @@ internal fun ConeDiagnostic.getCandidateSymbols(): Collection<FirBasedSymbol<*>>
} }
is ConeDiagnosticWithCandidates -> candidateSymbols is ConeDiagnosticWithCandidates -> candidateSymbols
else -> emptyList() 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.KtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList 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.fir.utils.FirRefWithValidityCheck
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveType import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveType
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
internal class KtFirAnnotationListForDeclaration private constructor( internal class KtFirAnnotationListForDeclaration private constructor(
@@ -20,9 +22,9 @@ internal class KtFirAnnotationListForDeclaration private constructor(
override val token: ValidityToken, override val token: ValidityToken,
) : KtAnnotationsList() { ) : KtAnnotationsList() {
override val annotations: List<KtAnnotationApplication> override val annotations: List<KtAnnotationApplication>
get() = firRef.withFir { fir -> get() = firRef.withFir(FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS) { fir ->
fir.annotations.map { annotation -> 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 -> override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplication> =
fir.annotations.mapNotNull { annotation -> firRef.withFir(FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS) { fir ->
if (annotation.fullyExpandedClassId(useSiteSession) != classId) return@mapNotNull null fir.annotations.mapNotNull { annotation ->
KtFirAnnotationApplicationForDeclaration(firRef, useSiteSession, annotation, token) if (annotation.fullyExpandedClassId(useSiteSession) != classId) return@mapNotNull null
annotation.toKtAnnotationApplication(useSiteSession)
}
} }
}
override val annotationClassIds: Collection<ClassId> override val annotationClassIds: Collection<ClassId>
get() = firRef.withFirByType(ResolveType.AnnotationType) { fir -> 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.KtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList 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.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.withValidityAssertion import org.jetbrains.kotlin.analysis.api.withValidityAssertion
@@ -21,7 +22,7 @@ internal class KtFirAnnotationListForType private constructor(
override val token: ValidityToken, override val token: ValidityToken,
) : KtAnnotationsList() { ) : KtAnnotationsList() {
override val annotations: List<KtAnnotationApplication> 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 { override fun containsAnnotation(classId: ClassId): Boolean = withValidityAssertion {
@@ -31,14 +32,13 @@ internal class KtFirAnnotationListForType private constructor(
override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplication> = withValidityAssertion { override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplication> = withValidityAssertion {
coneType.customAnnotations.mapNotNull { annotation -> coneType.customAnnotations.mapNotNull { annotation ->
if (annotation.fullyExpandedClassId(useSiteSession) != classId) return@mapNotNull null if (annotation.fullyExpandedClassId(useSiteSession) != classId) return@mapNotNull null
KtFirAnnotationApplicationImpl(annotation, useSiteSession, token) annotation.toKtAnnotationApplication(useSiteSession)
} }
} }
override val annotationClassIds: Collection<ClassId> override val annotationClassIds: Collection<ClassId>
get() = withValidityAssertion { coneType.customAnnotations.mapNotNull { it.fullyExpandedClassId(useSiteSession) } } get() = withValidityAssertion { coneType.customAnnotations.mapNotNull { it.fullyExpandedClassId(useSiteSession) } }
companion object { companion object {
fun create( fun create(
coneType: ConeKotlinType, coneType: ConeKotlinType,
@@ -25,9 +25,9 @@ internal object KtFirConstantValueConverter {
fun toNamedConstantValue( fun toNamedConstantValue(
argumentMapping: Map<String, FirExpression>, argumentMapping: Map<String, FirExpression>,
session: FirSession, session: FirSession,
): List<KtNamedConstantValue> = ): List<KtNamedAnnotationValue> =
argumentMapping.map { (name, expression) -> argumentMapping.map { (name, expression) ->
KtNamedConstantValue( KtNamedAnnotationValue(
name, name,
expression.convertConstantExpression(session) ?: KtUnsupportedAnnotationValue expression.convertConstantExpression(session) ?: KtUnsupportedAnnotationValue
) )
@@ -106,10 +106,13 @@ internal object KtFirConstantValueConverter {
argumentMapping?.entries?.forEach { (arg, param) -> argumentMapping?.entries?.forEach { (arg, param) ->
resultMap[param.name.asString()] = arg resultMap[param.name.asString()] = arg
} }
KtAnnotationAnnotationValue( KtAnnotationApplicationValue(
resolvedSymbol.callableId.classId, KtAnnotationApplication(
toNamedConstantValue(resultMap, session), resolvedSymbol.callableId.classId,
psi as? KtCallElement psi as? KtAnnotationEntry,
useSiteTarget = null,
toNamedConstantValue(resultMap, session),
)
) )
} else null } else null
} }
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder 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.annotations.KtFirAnnotationListForDeclaration
import org.jetbrains.kotlin.analysis.api.fir.findPsi import org.jetbrains.kotlin.analysis.api.fir.findPsi
import org.jetbrains.kotlin.analysis.api.fir.utils.cached import org.jetbrains.kotlin.analysis.api.fir.utils.cached
@@ -44,11 +44,11 @@ abstract class AbstractCompileTimeConstantEvaluatorTest(
appendLine(INDENT, values.joinToString(separator = "\n") { it.stringRepresentation() }) appendLine(INDENT, values.joinToString(separator = "\n") { it.stringRepresentation() })
append("]") append("]")
} }
is KtAnnotationAnnotationValue -> buildString { is KtAnnotationApplicationValue -> buildString {
append("KtAnnotationConstantValue(") append("KtAnnotationConstantValue(")
append(classId?.relativeClassName) append(annotationValue.classId?.relativeClassName)
append(", ") append(", ")
arguments.joinTo(this, separator = ", ", prefix = "(", postfix = ")") { annotationValue.arguments.joinTo(this, separator = ", ", prefix = "(", postfix = ")") {
"${it.name} = ${it.expression.stringRepresentation()}" "${it.name} = ${it.expression.stringRepresentation()}"
} }
append(")") append(")")
@@ -5,14 +5,14 @@
package org.jetbrains.kotlin.analysis.api.annotations package org.jetbrains.kotlin.analysis.api.annotations
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtCallElement import org.jetbrains.kotlin.psi.KtCallElement
public abstract class KtAnnotationApplication : ValidityTokenOwner { public class KtAnnotationApplication(
public abstract val classId: ClassId? public val classId: ClassId?,
public abstract val useSiteTarget: AnnotationUseSiteTarget? public val psi: KtAnnotationEntry?,
public abstract val psi: KtCallElement? public val useSiteTarget: AnnotationUseSiteTarget?,
public abstract val arguments: List<KtNamedConstantValue> public val arguments: List<KtNamedAnnotationValue>,
} )
@@ -6,8 +6,6 @@
package org.jetbrains.kotlin.analysis.api.annotations package org.jetbrains.kotlin.analysis.api.annotations
import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtCallElement
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.ConstantValueKind
@@ -23,7 +21,7 @@ import org.jetbrains.kotlin.types.ConstantValueKind
* *
* [KtLiteralAnnotationValue] covers first two kinds; * [KtLiteralAnnotationValue] covers first two kinds;
* [KtEnumEntryAnnotationValue] corresponds to enum types; * [KtEnumEntryAnnotationValue] corresponds to enum types;
* [KtAnnotationAnnotationValue] represents annotation types (with annotation fq name and arguments); and * [KtAnnotationApplicationValue] represents annotation types (with annotation fq name and arguments); and
* [KtArrayAnnotationValue] abstracts an array of [KtAnnotationValue]s. * [KtArrayAnnotationValue] abstracts an array of [KtAnnotationValue]s.
*/ */
public sealed class KtAnnotationValue( public sealed class KtAnnotationValue(
@@ -47,10 +45,8 @@ public class KtArrayAnnotationValue(
override val sourcePsi: KtElement?, override val sourcePsi: KtElement?,
) : KtAnnotationValue() ) : KtAnnotationValue()
public class KtAnnotationAnnotationValue( public class KtAnnotationApplicationValue(
public val classId: ClassId?, public val annotationValue: KtAnnotationApplication,
public val arguments: List<KtNamedConstantValue>,
override val sourcePsi: KtCallElement?,
) : KtAnnotationValue() ) : KtAnnotationValue()
public class KtEnumEntryAnnotationValue( public class KtEnumEntryAnnotationValue(
@@ -5,4 +5,4 @@
package org.jetbrains.kotlin.analysis.api.annotations package org.jetbrains.kotlin.analysis.api.annotations
public data class KtNamedConstantValue(val name: String, val expression: KtAnnotationValue) public data class KtNamedAnnotationValue(val name: String, val expression: KtAnnotationValue)
@@ -142,7 +142,7 @@ public object DebugSymbolRenderer {
append(KtConstantValueRenderer.render(value)) append(KtConstantValueRenderer.render(value))
} }
private fun Block.renderNamedConstantValue(value: KtNamedConstantValue) { private fun Block.renderNamedConstantValue(value: KtNamedAnnotationValue) {
append(value.name).append(" = ") append(value.name).append(" = ")
renderValue(value.expression) renderValue(value.expression)
} }
@@ -189,7 +189,7 @@ public object DebugSymbolRenderer {
is KtSymbol -> renderSymbolTag(value) is KtSymbol -> renderSymbolTag(value)
is KtType -> renderType(value) is KtType -> renderType(value)
is KtAnnotationValue -> renderConstantValue(value) is KtAnnotationValue -> renderConstantValue(value)
is KtNamedConstantValue -> renderNamedConstantValue(value) is KtNamedAnnotationValue -> renderNamedConstantValue(value)
is KtInitializerValue -> renderKtInitializerValue(value) is KtInitializerValue -> renderKtInitializerValue(value)
is KtAnnotationApplication -> renderAnnotationApplication(value) is KtAnnotationApplication -> renderAnnotationApplication(value)
is KtAnnotationsList -> renderAnnotationsList(value) is KtAnnotationsList -> renderAnnotationsList(value)
@@ -15,7 +15,7 @@ public object KtConstantValueRenderer {
private fun StringBuilder.renderConstantValue(value: KtAnnotationValue) { private fun StringBuilder.renderConstantValue(value: KtAnnotationValue) {
when (value) { when (value) {
is KtAnnotationAnnotationValue -> { is KtAnnotationApplicationValue -> {
renderAnnotationConstantValue(value) renderAnnotationConstantValue(value)
} }
is KtArrayAnnotationValue -> { is KtArrayAnnotationValue -> {
@@ -58,7 +58,11 @@ public object KtConstantValueRenderer {
append(value.callableId?.asSingleFqName()?.asString()) append(value.callableId?.asSingleFqName()?.asString())
} }
private fun StringBuilder.renderAnnotationConstantValue(value: KtAnnotationAnnotationValue) { private fun StringBuilder.renderAnnotationConstantValue(application: KtAnnotationApplicationValue) {
renderAnnotationApplication(application.annotationValue)
}
private fun StringBuilder.renderAnnotationApplication(value: KtAnnotationApplication) {
append(value.classId) append(value.classId)
if (value.arguments.isNotEmpty()) { if (value.arguments.isNotEmpty()) {
append("(") append("(")
@@ -79,7 +83,7 @@ public object KtConstantValueRenderer {
} }
} }
private fun StringBuilder.renderNamedConstantValueList(list: Collection<KtNamedConstantValue>) { private fun StringBuilder.renderNamedConstantValueList(list: Collection<KtNamedAnnotationValue>) {
renderWithSeparator(list, ", ") { namedValue -> renderWithSeparator(list, ", ") { namedValue ->
append(namedValue.name) append(namedValue.name)
append(" = ") append(" = ")
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.light.classes.symbol
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.impl.light.LightIdentifier import com.intellij.psi.impl.light.LightIdentifier
import org.jetbrains.kotlin.analysis.api.annotations.KtNamedConstantValue import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue
import org.jetbrains.kotlin.asJava.classes.cannotModify import org.jetbrains.kotlin.asJava.classes.cannotModify
import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightElementBase import org.jetbrains.kotlin.asJava.elements.KtLightElementBase
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.psi.KtElement
internal class FirAnnotationParameterList( internal class FirAnnotationParameterList(
parent: FirLightAbstractAnnotation, parent: FirLightAbstractAnnotation,
private val arguments: List<KtNamedConstantValue>, private val arguments: List<KtNamedAnnotationValue>,
) : KtLightElementBase(parent), PsiAnnotationParameterList { ) : KtLightElementBase(parent), PsiAnnotationParameterList {
private val _attributes: Array<PsiNameValuePair> by lazyPub { private val _attributes: Array<PsiNameValuePair> by lazyPub {
@@ -32,7 +32,7 @@ internal class FirAnnotationParameterList(
} }
private class FirNameValuePairForAnnotationArgument( private class FirNameValuePairForAnnotationArgument(
private val constantValue: KtNamedConstantValue, private val constantValue: KtNamedAnnotationValue,
parent: PsiElement parent: PsiElement
) : KtLightElementBase(parent), PsiNameValuePair { ) : KtLightElementBase(parent), PsiNameValuePair {
@@ -9,14 +9,14 @@ import com.intellij.psi.PsiAnnotationMemberValue
import com.intellij.psi.PsiAnnotationParameterList import com.intellij.psi.PsiAnnotationParameterList
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.impl.PsiImplUtil import com.intellij.psi.impl.PsiImplUtil
import org.jetbrains.kotlin.analysis.api.annotations.KtNamedConstantValue import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue
import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.psi.KtCallElement import org.jetbrains.kotlin.psi.KtCallElement
internal class FirLightSimpleAnnotation( internal class FirLightSimpleAnnotation(
private val fqName: String?, private val fqName: String?,
parent: PsiElement, parent: PsiElement,
private val arguments: List<KtNamedConstantValue> = listOf(), private val arguments: List<KtNamedAnnotationValue> = listOf(),
override val kotlinOrigin: KtCallElement? = null, override val kotlinOrigin: KtCallElement? = null,
) : FirLightAbstractAnnotation(parent) { ) : FirLightAbstractAnnotation(parent) {
@@ -177,8 +177,13 @@ internal fun KtAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiA
FirPsiArrayInitializerMemberValue(sourcePsi, parent) { arrayLiteralParent -> FirPsiArrayInitializerMemberValue(sourcePsi, parent) { arrayLiteralParent ->
values.mapNotNull { element -> element.toAnnotationMemberValue(arrayLiteralParent) } values.mapNotNull { element -> element.toAnnotationMemberValue(arrayLiteralParent) }
} }
is KtAnnotationAnnotationValue -> is KtAnnotationApplicationValue ->
FirLightSimpleAnnotation(classId?.relativeClassName?.asString(), parent, arguments, sourcePsi) FirLightSimpleAnnotation(
annotationValue.classId?.relativeClassName?.asString(),
parent,
annotationValue.arguments,
annotationValue.psi
)
else -> else ->
createPsiLiteral(parent)?.let { createPsiLiteral(parent)?.let {
when (it) { when (it) {