[FIR] Implement REPEATED_ANNOTATION for types refs ^KT-48652 Fixed

This commit is contained in:
Ivan Kochurkin
2021-09-28 02:11:23 +03:00
committed by teamcityserver
parent 3dc0935da4
commit 922ae607f6
7 changed files with 49 additions and 34 deletions
@@ -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<FirExpression> {
}
}
fun checkRepeatedAnnotation(
annotationContainer: FirAnnotationContainer?,
annotations: List<FirAnnotation>,
context: CheckerContext,
reporter: DiagnosticReporter
) {
if (annotations.size <= 1) return
val annotationsMap = hashMapOf<ConeKotlinType, MutableList<AnnotationUseSiteTarget?>>()
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)
}
}
@@ -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<ConeKotlinType, MutableList<AnnotationUseSiteTarget?>>()
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)
}
}
@@ -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
@@ -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
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
@Target(AnnotationTarget.TYPE)
annotation class A
@@ -1,6 +0,0 @@
@Target(AnnotationTarget.TYPE)
annotation class A
typealias Gen<T> = List<@A T>
typealias Test1 = Gen<@A Int>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
@Target(AnnotationTarget.TYPE)
annotation class A