From 4b955944ffd5a5319a39f66faa795193f5c59854 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Tue, 24 Jan 2023 14:04:05 +0100 Subject: [PATCH] [AA] KtAnnotationApplication: add 'index' parameter it is required for lazy annotations resolve ^KT-56046 --- .../annotations/KtFe10AnnotationsList.kt | 11 ++++---- .../descriptorBased/base/Kt1DescUtils.kt | 25 ++++++++++++------- .../descriptors/utils/renderAnnotations.kt | 4 +-- .../kotlin/analysis/api/fir/FirUtils.kt | 14 +++++++---- .../annotations/KtFirAnnotationListForType.kt | 10 ++++---- .../api/fir/annotations/firAnnotationUtils.kt | 16 ++++++------ .../evaluate/FirAnnotationValueConverter.kt | 14 +++++------ .../annotations/KtAnnotationApplication.kt | 8 ++++-- 8 files changed, 59 insertions(+), 43 deletions(-) diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/annotations/KtFe10AnnotationsList.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/annotations/KtFe10AnnotationsList.kt index 07afaee6a41..ef6262692c0 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/annotations/KtFe10AnnotationsList.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/annotations/KtFe10AnnotationsList.kt @@ -29,9 +29,9 @@ internal class KtFe10AnnotationsList private constructor( override val annotations: List get() = withValidityAssertion { - fe10Annotations.mapNotNull { annotation -> + fe10Annotations.mapIndexedNotNull { index, annotation -> if (annotation.annotationClass.classId in annotationsToIgnore) null - else annotation.toKtAnnotationApplication(analysisContext) + else annotation.toKtAnnotationApplication(analysisContext, index) } } @@ -61,9 +61,10 @@ internal class KtFe10AnnotationsList private constructor( override fun annotationsByClassId(classId: ClassId): List = withValidityAssertion { if (classId in annotationsToIgnore) return@withValidityAssertion emptyList() - fe10Annotations.mapNotNull { annotation -> - if (annotation.annotationClass?.maybeLocalClassId != classId) return@mapNotNull null - annotation.toKtAnnotationApplication(analysisContext) + + fe10Annotations.mapIndexedNotNull { index, annotation -> + if (annotation.annotationClass?.maybeLocalClassId != classId) return@mapIndexedNotNull null + annotation.toKtAnnotationApplication(analysisContext, index) } } diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt index 1df129da1c6..0eb569cf390 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 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. */ @@ -33,7 +33,10 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.idea.KotlinLanguage -import org.jetbrains.kotlin.load.java.descriptors.* +import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor +import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor +import org.jetbrains.kotlin.load.java.descriptors.JavaForKotlinOverridePropertyDescriptor +import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor import org.jetbrains.kotlin.load.java.sources.JavaSourceElement import org.jetbrains.kotlin.load.kotlin.toSourceElement import org.jetbrains.kotlin.name.CallableId @@ -422,19 +425,21 @@ internal tailrec fun KotlinBuiltIns.areSameArrayTypeIgnoringProjections(left: Ko } -internal fun List>.expandArrayAnnotationValue(containingArrayType: KotlinType, analysisContext: Fe10AnalysisContext) - : List = flatMap { constantValue -> +internal fun List>.expandArrayAnnotationValue( + containingArrayType: KotlinType, + analysisContext: Fe10AnalysisContext, +): List = flatMapIndexed { index: Int, constantValue: ConstantValue<*> -> val constantType = constantValue.getType(analysisContext.resolveSession.moduleDescriptor) if (analysisContext.builtIns.areSameArrayTypeIgnoringProjections(containingArrayType, constantType)) { // If an element in the array has the same type as the containing array, it's a spread component that needs // to be expanded here. (It should have the array element type instead.) (constantValue as ArrayValue).value.expandArrayAnnotationValue(containingArrayType, analysisContext) } else { - listOf(constantValue.toKtAnnotationValue(analysisContext)) + listOf(constantValue.toKtAnnotationValue(analysisContext, index)) } } -internal fun ConstantValue<*>.toKtAnnotationValue(analysisContext: Fe10AnalysisContext): KtAnnotationValue { +internal fun ConstantValue<*>.toKtAnnotationValue(analysisContext: Fe10AnalysisContext, index: Int): KtAnnotationValue { return when (this) { is ArrayValue -> { val arrayType = getType(analysisContext.resolveSession.moduleDescriptor) @@ -456,6 +461,7 @@ internal fun ConstantValue<*>.toKtAnnotationValue(analysisContext: Fe10AnalysisC psi = null, useSiteTarget = null, arguments = value.getKtNamedAnnotationArguments(analysisContext), + index = index, ) ) } @@ -602,18 +608,19 @@ internal fun createKtInitializerValue( return KtNonConstantInitializerValue(initializer) } -internal fun AnnotationDescriptor.toKtAnnotationApplication(analysisContext: Fe10AnalysisContext): KtAnnotationApplication { +internal fun AnnotationDescriptor.toKtAnnotationApplication(analysisContext: Fe10AnalysisContext, index: Int): KtAnnotationApplication { return KtAnnotationApplication( annotationClass?.maybeLocalClassId, (source as? PsiSourceElement)?.psi as? KtCallElement, (this as? LazyAnnotationDescriptor)?.annotationEntry?.useSiteTarget?.getAnnotationUseSiteTarget(), getKtNamedAnnotationArguments(analysisContext), + index, ) } -internal fun AnnotationDescriptor.getKtNamedAnnotationArguments(analysisContext: Fe10AnalysisContext) = +internal fun AnnotationDescriptor.getKtNamedAnnotationArguments(analysisContext: Fe10AnalysisContext): List = allValueArguments.map { (name, value) -> - KtNamedAnnotationValue(name, value.toKtAnnotationValue(analysisContext)) + KtNamedAnnotationValue(name, value.toKtAnnotationValue(analysisContext, index = -1)) } diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/renderAnnotations.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/renderAnnotations.kt index 9b7dddfb796..aab3dc979f6 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/renderAnnotations.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/utils/renderAnnotations.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 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. */ @@ -41,7 +41,7 @@ internal fun PrettyPrinter.renderFe10Annotations( printCollectionIfNotEmpty(valueArguments, separator = ", ", prefix = "(", postfix = ")") { (name, value) -> append(name.render()) append(" = ") - append(value.toKtAnnotationValue(analysisContext).renderAsSourceCode()) + append(value.toKtAnnotationValue(analysisContext, -1).renderAsSourceCode()) } append(separator) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt index 4634b004184..a0dca2117cc 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 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. */ @@ -12,13 +12,16 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic -import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference -import org.jetbrains.kotlin.fir.resolve.diagnostics.* +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithCandidates +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithSymbol +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeHiddenCandidateError import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.psi.KtCallElement @@ -62,7 +65,7 @@ internal fun ConeDiagnostic.getCandidateSymbols(): Collection> else -> emptyList() } -internal fun FirAnnotation.toKtAnnotationApplication(useSiteSession: FirSession): KtAnnotationApplication { +internal fun FirAnnotation.toKtAnnotationApplication(useSiteSession: FirSession, index: Int): KtAnnotationApplication { return KtAnnotationApplication( toAnnotationClassId(useSiteSession), psi as? KtCallElement, @@ -70,6 +73,7 @@ internal fun FirAnnotation.toKtAnnotationApplication(useSiteSession: FirSession) FirAnnotationValueConverter.toNamedConstantValue( mapAnnotationParameters(this), useSiteSession, - ) + ), + index, ) } \ No newline at end of file diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt index e37ded50109..7689b04ce12 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/KtFirAnnotationListForType.kt @@ -29,8 +29,8 @@ internal class KtFirAnnotationListForType private constructor( ) : KtAnnotationsList() { override val annotations: List get() = withValidityAssertion { - coneType.customAnnotationsWithLazyResolve(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING).map { - it.toKtAnnotationApplication(useSiteSession) + coneType.customAnnotationsWithLazyResolve(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING).mapIndexed { index, annotation -> + annotation.toKtAnnotationApplication(useSiteSession, index) } } @@ -50,9 +50,9 @@ internal class KtFirAnnotationListForType private constructor( } override fun annotationsByClassId(classId: ClassId): List = withValidityAssertion { - coneType.customAnnotationsWithLazyResolve(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING).mapNotNull { annotation -> - if (annotation.toAnnotationClassId(useSiteSession) != classId) return@mapNotNull null - annotation.toKtAnnotationApplication(useSiteSession) + coneType.customAnnotationsWithLazyResolve(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING).mapIndexedNotNull { index, annotation -> + if (annotation.toAnnotationClassId(useSiteSession) != classId) return@mapIndexedNotNull null + annotation.toKtAnnotationApplication(useSiteSession, index) } } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt index 6674f3749da..602c8794d7e 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/annotations/firAnnotationUtils.kt @@ -42,14 +42,14 @@ internal fun annotationsByClassId( annotationContainer: FirAnnotationContainer = firSymbol.fir, ): List = if (firSymbol.isFromCompilerRequiredAnnotationsPhase(classId)) { - annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol).mapNotNull { annotation -> - if (annotation.toAnnotationClassIdSafe(useSiteSession) != classId) return@mapNotNull null - annotation.toKtAnnotationApplication(useSiteSession) + annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol).mapIndexedNotNull { index, annotation -> + if (annotation.toAnnotationClassIdSafe(useSiteSession) != classId) return@mapIndexedNotNull null + annotation.toKtAnnotationApplication(useSiteSession, index) } } else { - annotationContainer.resolvedAnnotationsWithArguments(firSymbol).mapNotNull { annotation -> - if (annotation.toAnnotationClassId(useSiteSession) != classId) return@mapNotNull null - annotation.toKtAnnotationApplication(useSiteSession) + annotationContainer.resolvedAnnotationsWithArguments(firSymbol).mapIndexedNotNull { index, annotation -> + if (annotation.toAnnotationClassId(useSiteSession) != classId) return@mapIndexedNotNull null + annotation.toKtAnnotationApplication(useSiteSession, index) } } @@ -57,8 +57,8 @@ internal fun annotations( firSymbol: FirBasedSymbol<*>, useSiteSession: FirSession, annotationContainer: FirAnnotationContainer = firSymbol.fir, -): List = annotationContainer.resolvedAnnotationsWithArguments(firSymbol).map { annotation -> - annotation.toKtAnnotationApplication(useSiteSession) +): List = annotationContainer.resolvedAnnotationsWithArguments(firSymbol).mapIndexed { index, annotation -> + annotation.toKtAnnotationApplication(useSiteSession, index) } internal fun annotationClassIds( diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirAnnotationValueConverter.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirAnnotationValueConverter.kt index 012fa719502..95d17642aae 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirAnnotationValueConverter.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/evaluate/FirAnnotationValueConverter.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 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. */ @@ -11,13 +11,11 @@ import org.jetbrains.kotlin.analysis.api.components.KtConstantEvaluationMode import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol -import org.jetbrains.kotlin.fir.analysis.checkers.toClassLikeSymbol import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.psi -import org.jetbrains.kotlin.fir.realPsi import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedTypeQualifierError @@ -28,8 +26,9 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.types.ConeErrorType import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.parents +import org.jetbrains.kotlin.psi.KtCallElement +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.resolve.ArrayFqNames internal object FirAnnotationValueConverter { @@ -73,8 +72,7 @@ internal object FirAnnotationValueConverter { fun toConstantValue( firExpression: FirExpression, session: FirSession, - ): KtAnnotationValue? = - firExpression.convertConstantExpression(session) + ): KtAnnotationValue? = firExpression.convertConstantExpression(session) private fun FirExpression.convertConstantExpression( session: FirSession, @@ -112,12 +110,14 @@ internal object FirAnnotationValueConverter { resolvedArgumentMapping?.entries?.forEach { (arg, param) -> resultMap[param.name] = arg } + KtAnnotationApplicationValue( KtAnnotationApplication( resolvedSymbol.callableId.classId, psi as? KtCallElement, useSiteTarget = null, toNamedConstantValue(resultMap, session), + index = -1, ) ) } else null diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotationApplication.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotationApplication.kt index 5064817166b..102eccedf45 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotationApplication.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/annotations/KtAnnotationApplication.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 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. */ @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.analysis.api.annotations 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 /** @@ -42,4 +41,9 @@ public data class KtAnnotationApplication( * A list of annotation arguments which were applied when constructing annotation. Every argument is [KtAnnotationValue] */ public val arguments: List, + + /** + * An index of the annotation in an owner. Can be `-1` in case of annotation arguments + */ + public val index: Int, ) \ No newline at end of file