From 7f9118d0f2b551e64bea626d3d6c31fc1eb8584a Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Fri, 5 May 2023 17:11:57 +0200 Subject: [PATCH] [FIR] Resolve property return type before resolving its annotations This fixes TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM in a declaration like `@Ann(myConst) const val myConst = ""`. #KT-58080 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 6 +++++ ...sticCompilerFE10TestDataTestGenerated.java | 6 +++++ ...eeOldFrontendDiagnosticsTestGenerated.java | 6 +++++ ...siOldFrontendDiagnosticsTestGenerated.java | 6 +++++ .../FirDeclarationsResolveTransformer.kt | 23 ++++++++----------- .../tests/properties/constAnnotationCycle.kt | 6 +++++ .../test/runners/DiagnosticTestGenerated.java | 6 +++++ 7 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/properties/constAnnotationCycle.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index a7891b1e3f8..c24c63d9901 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -24902,6 +24902,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/properties"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); } + @Test + @TestMetadata("constAnnotationCycle.kt") + public void testConstAnnotationCycle() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/constAnnotationCycle.kt"); + } + @Test @TestMetadata("extensionPropertyMustHaveAccessorsOrBeAbstract.kt") public void testExtensionPropertyMustHaveAccessorsOrBeAbstract() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index 731ead4a0a0..ee138cc2fd3 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -24902,6 +24902,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/properties"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); } + @Test + @TestMetadata("constAnnotationCycle.kt") + public void testConstAnnotationCycle() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/constAnnotationCycle.kt"); + } + @Test @TestMetadata("extensionPropertyMustHaveAccessorsOrBeAbstract.kt") public void testExtensionPropertyMustHaveAccessorsOrBeAbstract() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index b743e5194a0..354291ada0a 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -24902,6 +24902,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/properties"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); } + @Test + @TestMetadata("constAnnotationCycle.kt") + public void testConstAnnotationCycle() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/constAnnotationCycle.kt"); + } + @Test @TestMetadata("extensionPropertyMustHaveAccessorsOrBeAbstract.kt") public void testExtensionPropertyMustHaveAccessorsOrBeAbstract() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index 773203a90b8..71f8404b72a 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -24908,6 +24908,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/properties"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); } + @Test + @TestMetadata("constAnnotationCycle.kt") + public void testConstAnnotationCycle() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/constAnnotationCycle.kt"); + } + @Test @TestMetadata("extensionPropertyMustHaveAccessorsOrBeAbstract.kt") public void testExtensionPropertyMustHaveAccessorsOrBeAbstract() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index ee5b28d3730..299020442f1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -145,12 +145,20 @@ open class FirDeclarationsResolveTransformer( context.withProperty(property) { context.forPropertyInitializer { if (!initializerIsAlreadyResolved) { - property.transformChildrenWithoutComponents(returnTypeRefBeforeResolve) - property.replaceBodyResolveState(FirPropertyBodyResolveState.INITIALIZER_RESOLVED) + val resolutionMode = withExpectedType(returnTypeRefBeforeResolve) + property.transformReturnTypeRef(transformer, resolutionMode) + .transformInitializer(transformer, resolutionMode) + .transformTypeParameters(transformer, resolutionMode) + .replaceBodyResolveState(FirPropertyBodyResolveState.INITIALIZER_RESOLVED) } + // Return type needs to be resolved before resolving annotations (transformOtherChildren) because of a possible cycle + // @Ann(myConst) const val myConst = "" if (property.initializer != null) { storeVariableReturnType(property) } + if (!initializerIsAlreadyResolved) { + property.transformOtherChildren(transformer, data) + } val canResolveBackingFieldEarly = property.hasExplicitBackingField || property.returnTypeRef is FirResolvedTypeRef if (!initializerIsAlreadyResolved && canResolveBackingFieldEarly) { property.transformBackingField(transformer, withExpectedType(property.returnTypeRef)) @@ -412,17 +420,6 @@ open class FirDeclarationsResolveTransformer( return variable } - /** - * This function is expected to transform everything but property accessors, backing field and delegate - */ - private fun FirProperty.transformChildrenWithoutComponents(returnTypeRef: FirTypeRef): FirProperty { - val data = withExpectedType(returnTypeRef) - return transformReturnTypeRef(transformer, data) - .transformInitializer(transformer, data) - .transformTypeParameters(transformer, data) - .transformOtherChildren(transformer, data) - } - private fun FirProperty.transformAccessors(mayResolveSetter: Boolean = true) { var enhancedTypeRef = returnTypeRef if (bodyResolveState < FirPropertyBodyResolveState.INITIALIZER_AND_GETTER_RESOLVED) { diff --git a/compiler/testData/diagnostics/tests/properties/constAnnotationCycle.kt b/compiler/testData/diagnostics/tests/properties/constAnnotationCycle.kt new file mode 100644 index 00000000000..4dc198a2370 --- /dev/null +++ b/compiler/testData/diagnostics/tests/properties/constAnnotationCycle.kt @@ -0,0 +1,6 @@ +// FIR_IDENTICAL + +annotation class Anno(val value: String) + +@Anno(constant) +const val constant = "OK" \ No newline at end of file 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 9406282acea..0e6a951f598 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 @@ -25680,6 +25680,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/properties"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true); } + @Test + @TestMetadata("constAnnotationCycle.kt") + public void testConstAnnotationCycle() throws Exception { + runTest("compiler/testData/diagnostics/tests/properties/constAnnotationCycle.kt"); + } + @Test @TestMetadata("extensionPropertyMustHaveAccessorsOrBeAbstract.kt") public void testExtensionPropertyMustHaveAccessorsOrBeAbstract() throws Exception {