From 922ae607f6bdcc5a2b9b136a2686ddc918b9278a Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 28 Sep 2021 02:11:23 +0300 Subject: [PATCH] [FIR] Implement `REPEATED_ANNOTATION` for types refs ^KT-48652 Fixed --- .../analysis/checkers/FirAnnotationHelpers.kt | 24 ++++++++++++++ .../declaration/FirAnnotationChecker.kt | 33 ++++++++++++------- .../kotlin/fir/resolve/TypeExpansionUtils.kt | 2 +- ...peAliasExpansionRepeatedAnnotations.fir.kt | 16 --------- .../typeAliasExpansionRepeatedAnnotations.kt | 1 + ...iasRhsRepeatedAnnotationInArguments.fir.kt | 6 ---- ...pealiasRhsRepeatedAnnotationInArguments.kt | 1 + 7 files changed, 49 insertions(+), 34 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/typealias/typeAliasExpansionRepeatedAnnotations.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotationInArguments.fir.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt index 88aa7477198..abdc8deea82 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor import org.jetbrains.kotlin.fir.expressions.* @@ -30,6 +31,7 @@ import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirErrorTypeRef import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.name.StandardClassIds @@ -175,3 +177,25 @@ private fun FirExpression.unfoldArrayOrVararg(): List { } } +fun checkRepeatedAnnotation( + annotationContainer: FirAnnotationContainer?, + annotations: List, + context: CheckerContext, + reporter: DiagnosticReporter +) { + if (annotations.size <= 1) return + + val annotationsMap = hashMapOf>() + + for (annotation in annotations) { + val useSiteTarget = annotation.useSiteTarget ?: annotationContainer?.getDefaultUseSiteTarget(annotation, context) + val existingTargetsForAnnotation = annotationsMap.getOrPut(annotation.annotationTypeRef.coneType) { arrayListOf() } + + withSuppressedDiagnostics(annotation, context) { + checkRepeatedAnnotation(useSiteTarget, existingTargetsForAnnotation, annotation, context, reporter) + } + + existingTargetsForAnnotation.add(useSiteTarget) + } +} + diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt index 66e8753ee76..7e37b25bf0b 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt @@ -20,8 +20,11 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.packageFqName import org.jetbrains.kotlin.fir.resolve.fqName +import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.coneTypeSafe +import org.jetbrains.kotlin.fir.types.customAnnotations import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.StandardClassIds @@ -56,11 +59,15 @@ object FirAnnotationChecker : FirAnnotatedDeclarationChecker() { } checkRepeatedAnnotations(declaration, context, reporter) + if (declaration is FirProperty) { checkRepeatedAnnotationsInProperty(declaration, context, reporter) + } else if (declaration is FirCallableDeclaration) { + if (declaration.source?.kind !is FirFakeSourceElementKind) { + checkRepeatedAnnotations(declaration.returnTypeRef.coneTypeSafe(), context, reporter) + } } else if (declaration is FirTypeAlias) { - checkRepeatedAnnotations(declaration.expandedTypeRef, context, reporter) - // TODO: KT-48652, implement after KT-48651 + checkRepeatedAnnotations(declaration.expandedTypeRef.coneType, context, reporter) } } @@ -211,17 +218,21 @@ object FirAnnotationChecker : FirAnnotatedDeclarationChecker() { context: CheckerContext, reporter: DiagnosticReporter ) { - val annotationsMap = hashMapOf>() + checkRepeatedAnnotation(annotationContainer, annotationContainer.annotations, context, reporter) + } - for (annotation in annotationContainer.annotations) { - val useSiteTarget = annotation.useSiteTarget ?: annotationContainer.getDefaultUseSiteTarget(annotation, context) - val existingTargetsForAnnotation = annotationsMap.getOrPut(annotation.annotationTypeRef.coneType) { arrayListOf() } - - withSuppressedDiagnostics(annotation, context) { - checkRepeatedAnnotation(useSiteTarget, existingTargetsForAnnotation, annotation, context, reporter) + private fun checkRepeatedAnnotations( + type: ConeKotlinType?, + context: CheckerContext, + reporter: DiagnosticReporter + ) { + if (type == null) return + val fullyExpandedType = type.fullyExpandedType(context.session) + checkRepeatedAnnotation(null, fullyExpandedType.attributes.customAnnotations, context, reporter) + for (typeArgument in fullyExpandedType.typeArguments) { + if (typeArgument is ConeKotlinType) { + checkRepeatedAnnotations(typeArgument, context, reporter) } - - existingTargetsForAnnotation.add(useSiteTarget) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/TypeExpansionUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/TypeExpansionUtils.kt index 5022526ca98..1c20c972446 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/TypeExpansionUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/TypeExpansionUtils.kt @@ -120,7 +120,7 @@ private fun mapTypeAliasArguments( is ConeDefinitelyNotNullType, is ConeTypeParameterTypeImpl, is ConeFlexibleType -> { - mappedType.withAttributes(type.attributes, useSiteSession.typeContext) + mappedType.withAttributes(type.attributes.add(mappedType.attributes), useSiteSession.typeContext) } null -> return mappedProjection else -> mappedType diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasExpansionRepeatedAnnotations.fir.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasExpansionRepeatedAnnotations.fir.kt deleted file mode 100644 index faeac4d3906..00000000000 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasExpansionRepeatedAnnotations.fir.kt +++ /dev/null @@ -1,16 +0,0 @@ -@Target(AnnotationTarget.TYPE) -annotation class A - -typealias AInt = @A Int -typealias AI = AInt - -typealias Test1 = @A AInt -typealias Test2 = @A AI -typealias Test3 = List<@A AInt> -typealias Test4 = List<@A AI> - -val testProperty1: @A AInt = 0 -val testProperty2: @A AI = 0 - -fun testFunction1(x: @A AInt): @A AInt = x -fun testFunction2(x: @A AI): @A AI = x \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasExpansionRepeatedAnnotations.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasExpansionRepeatedAnnotations.kt index 72359e44324..e2dff5a0171 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasExpansionRepeatedAnnotations.kt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasExpansionRepeatedAnnotations.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL @Target(AnnotationTarget.TYPE) annotation class A diff --git a/compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotationInArguments.fir.kt b/compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotationInArguments.fir.kt deleted file mode 100644 index 5936c10fb09..00000000000 --- a/compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotationInArguments.fir.kt +++ /dev/null @@ -1,6 +0,0 @@ -@Target(AnnotationTarget.TYPE) -annotation class A - -typealias Gen = List<@A T> - -typealias Test1 = Gen<@A Int> diff --git a/compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotationInArguments.kt b/compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotationInArguments.kt index 9a0154574dc..8674e55360e 100644 --- a/compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotationInArguments.kt +++ b/compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotationInArguments.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL @Target(AnnotationTarget.TYPE) annotation class A