From 12ce433bc2e176063a5a90516c83374b21ecd9d6 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 14 Jun 2022 13:37:29 +0300 Subject: [PATCH] [FE] Don't report cycle on annotation parameters if argument is vararg or array ^KT-52742 Fixed ^KT-47932 --- ...isCompilerTestFE10TestdataTestGenerated.java | 6 ++++++ .../FirOldFrontendDiagnosticsTestGenerated.java | 6 ++++++ ...ndDiagnosticsWithLightTreeTestGenerated.java | 6 ++++++ .../FirAnnotationClassDeclarationChecker.kt | 1 + .../checkers/CyclicAnnotationsChecker.kt | 4 +++- .../annotations/cycleInParameters_after.kt | 2 +- .../annotations/cycleInParameters_array.kt | 11 +++++++++++ .../annotations/cycleInParameters_array.txt | 17 +++++++++++++++++ .../annotations/cycleInParameters_before.kt | 2 +- .../repeatable/containerArguments_1_5.kt | 3 +-- .../repeatable/containerArguments_1_6.kt | 3 +-- .../test/runners/DiagnosticTestGenerated.java | 6 ++++++ 12 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.kt create mode 100644 compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.txt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index dee506d13f4..52914ef7910 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -1188,6 +1188,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/annotations/cycleInParameters_after.kt"); } + @Test + @TestMetadata("cycleInParameters_array.kt") + public void testCycleInParameters_array() throws Exception { + runTest("compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.kt"); + } + @Test @TestMetadata("cycleInParameters_before.kt") public void testCycleInParameters_before() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 4171c41577e..9e0021461ad 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -1188,6 +1188,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/annotations/cycleInParameters_after.kt"); } + @Test + @TestMetadata("cycleInParameters_array.kt") + public void testCycleInParameters_array() throws Exception { + runTest("compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.kt"); + } + @Test @TestMetadata("cycleInParameters_before.kt") public void testCycleInParameters_before() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 3306ab7d052..628e178b0f8 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -1188,6 +1188,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/annotations/cycleInParameters_after.kt"); } + @Test + @TestMetadata("cycleInParameters_array.kt") + public void testCycleInParameters_array() throws Exception { + runTest("compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.kt"); + } + @Test @TestMetadata("cycleInParameters_before.kt") public void testCycleInParameters_before() throws Exception { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt index 89e7c7f97a6..974bc9b5040 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationClassDeclarationChecker.kt @@ -192,6 +192,7 @@ object FirAnnotationClassDeclarationChecker : FirRegularClassChecker() { fun parameterHasCycle(ownedAnnotation: FirRegularClassSymbol, parameter: FirValueParameterSymbol): Boolean { val returnType = parameter.resolvedReturnTypeRef.coneType return when { + parameter.isVararg || returnType.isNonPrimitiveArray -> false returnType.typeArguments.isNotEmpty() -> { if (returnType.classId == StandardClassIds.KClass) return false for (argument in returnType.typeArguments) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/CyclicAnnotationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/CyclicAnnotationsChecker.kt index f9e5e43d659..ea23660d76d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/CyclicAnnotationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/CyclicAnnotationsChecker.kt @@ -13,7 +13,9 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.diagnostics.Errors.CYCLE_IN_ANNOTATION_PARAMETER import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.resolve.calls.components.isVararg import org.jetbrains.kotlin.types.UnwrappedType +import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext.isArrayOrNullableArray object CyclicAnnotationsChecker : DeclarationChecker { override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { @@ -52,6 +54,7 @@ object CyclicAnnotationsChecker : DeclarationChecker { fun parameterHasCycle(ownedAnnotation: ClassDescriptor, parameterDescriptor: ValueParameterDescriptor): Boolean { val returnType = parameterDescriptor.returnType?.unwrap() ?: return false return when { + parameterDescriptor.isVararg || returnType.isArrayOrNullableArray() -> false returnType.arguments.isNotEmpty() && !ReflectionTypes.isKClassType(returnType) -> { for (argument in returnType.arguments) { if (!argument.isStarProjection) { @@ -83,4 +86,3 @@ object CyclicAnnotationsChecker : DeclarationChecker { } } } - diff --git a/compiler/testData/diagnostics/tests/annotations/cycleInParameters_after.kt b/compiler/testData/diagnostics/tests/annotations/cycleInParameters_after.kt index 6572b9cfc83..8d4a0da7715 100644 --- a/compiler/testData/diagnostics/tests/annotations/cycleInParameters_after.kt +++ b/compiler/testData/diagnostics/tests/annotations/cycleInParameters_after.kt @@ -6,7 +6,7 @@ import kotlin.reflect.KClass annotation class X(val value: X) // error -annotation class Y(val value: Array) // error +annotation class Y(val value: Array) //no error annotation class Z1(val a: Z2, val b: Z2) // error annotation class Z2(val value: Z1) // error diff --git a/compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.kt b/compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.kt new file mode 100644 index 00000000000..89bdaac80b1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.kt @@ -0,0 +1,11 @@ +// FIR_IDENTICAL +// LANGUAGE: +ProhibitCyclesInAnnotations +// ISSUE: KT-52742 + +annotation class AnnotationWithArray( + val array: Array +) + +annotation class AnnotationWithVararg( + vararg val args: AnnotationWithVararg +) diff --git a/compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.txt b/compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.txt new file mode 100644 index 00000000000..aeb33e1aa4f --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.txt @@ -0,0 +1,17 @@ +package + +public final annotation class AnnotationWithArray : kotlin.Annotation { + public constructor AnnotationWithArray(/*0*/ array: kotlin.Array) + public final val array: kotlin.Array + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final annotation class AnnotationWithVararg : kotlin.Annotation { + public constructor AnnotationWithVararg(/*0*/ vararg args: AnnotationWithVararg /*kotlin.Array*/) + public final val args: kotlin.Array + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/annotations/cycleInParameters_before.kt b/compiler/testData/diagnostics/tests/annotations/cycleInParameters_before.kt index e1c8be469d2..eb5a6a9f0c2 100644 --- a/compiler/testData/diagnostics/tests/annotations/cycleInParameters_before.kt +++ b/compiler/testData/diagnostics/tests/annotations/cycleInParameters_before.kt @@ -6,7 +6,7 @@ import kotlin.reflect.KClass annotation class X(val value: X) // error -annotation class Y(val value: Array) // error +annotation class Y(val value: Array) // no error annotation class Z1(val a: Z2, val b: Z2) // error annotation class Z2(val value: Z1) // error diff --git a/compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_5.kt b/compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_5.kt index ba4363dbf02..c611b9d84df 100644 --- a/compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_5.kt +++ b/compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_5.kt @@ -28,9 +28,8 @@ annotation class C5(val value: Array, val irrelevant: String) annotation class A6 annotation class C6(val irrelevant: Double, val value: Array = []) -// Should be an error after fixing KT-47932. @R(A7::class) -annotation class A7(val value: Array) +annotation class A7(val value: Array) diff --git a/compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_6.kt b/compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_6.kt index b8e94dda5c4..a170287a84a 100644 --- a/compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_6.kt +++ b/compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_6.kt @@ -28,9 +28,8 @@ annotation class C5(val value: Array, val irrelevant: String) annotation class A6 annotation class C6(val irrelevant: Double, val value: Array = []) -// Should be an error after fixing KT-47932. @R(A7::class) -annotation class A7(val value: Array) +annotation class A7(val value: Array) diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 15a17fc9fee..7d04eca9231 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -1188,6 +1188,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/annotations/cycleInParameters_after.kt"); } + @Test + @TestMetadata("cycleInParameters_array.kt") + public void testCycleInParameters_array() throws Exception { + runTest("compiler/testData/diagnostics/tests/annotations/cycleInParameters_array.kt"); + } + @Test @TestMetadata("cycleInParameters_before.kt") public void testCycleInParameters_before() throws Exception {