From 15b1e429d73f5396b6cc4729398b8e763aa5f3ed Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 18 Nov 2022 18:12:58 +0100 Subject: [PATCH] [compiler] introduce dedicated Fir declaration for dangling modifier lists (KTIJ-23008) ensure fir annotations are included in FirDanglingModifierList and resolved, dedicated DanglingTopLevelModifierListStructureElement exists for top level lists only, class level lists are processed by containing structure element --- ...ceModuleReferenceResolveTestGenerated.java | 40 ++++++++++++ ...ceModuleReferenceResolveTestGenerated.java | 40 ++++++++++++ ...ceModuleReferenceResolveTestGenerated.java | 34 ++++++++++ ...ceModuleReferenceResolveTestGenerated.java | 40 ++++++++++++ ...ceModuleReferenceResolveTestGenerated.java | 40 ++++++++++++ .../DanglingAnnotationsResolvedAnonymous.kt | 10 +++ .../DanglingAnnotationsResolvedAnonymous.txt | 2 + .../DanglingAnnotationsResolvedClass.kt | 6 ++ .../DanglingAnnotationsResolvedClass.txt | 2 + .../DanglingAnnotationsResolvedLocal.kt | 9 +++ .../DanglingAnnotationsResolvedLocal.txt | 2 + .../DanglingAnnotationsResolvedTopLevel.kt | 3 + .../DanglingAnnotationsResolvedTopLevel.txt | 2 + .../withErrors/DanglingAnnotations.kt | 8 +++ .../low/level/api/fir/api/FirDesignation.kt | 11 +++- ...extCollectingDiagnosticCollectorVisitor.kt | 7 +- .../api/fir/file/structure/FileStructure.kt | 40 ++++++++++-- .../file/structure/FileStructureElement.kt | 8 ++- .../fir/file/structure/FirElementsRecorder.kt | 1 + .../LLFirModuleLazyDeclarationResolver.kt | 17 ++++- .../api/fir/util/contrainingFileUtils.kt | 2 + .../level/api/fir/util/declarationUtils.kt | 9 +-- .../danglingAnnotationClassLevel.kt | 16 +++++ .../danglingAnnotationTopLevel.kt | 1 + .../annotations/danglingAnnotation.kt | 3 + .../annotations/danglingAnnotation.txt | 6 ++ .../annotations/danglingAnnotationInClass.kt | 5 ++ .../annotations/danglingAnnotationInClass.txt | 6 ++ .../invalidCode/secondaryConstructor.kt | 5 ++ .../invalidCode/secondaryConstructor.txt | 6 ++ .../FirLazyBodiesCalculatorTestGenerated.java | 12 ++++ .../api/fir/GetOrBuildFirTestGenerated.java | 18 ++++++ .../AbstractFirContextCollectionTest.kt | 3 + .../FirContextCollectionTestGenerated.java | 12 ++++ .../structure/AbstractFileStructureTest.kt | 12 +++- .../structure/FileStructureTestGenerated.java | 12 ++++ .../expression/FirOptInUsageBaseChecker.kt | 2 +- .../converter/DeclarationsConverter.kt | 24 ++++++- ...ghtTree2FirConverterTestCaseGenerated.java | 10 +++ .../kotlin/fir/builder/RawFirBuilder.kt | 31 ++++++++- .../danglingAnnotationsClassLevel.kt | 22 +++++++ ...nglingAnnotationsClassLevel.lazyBodies.txt | 33 ++++++++++ .../danglingAnnotationsClassLevel.txt | 50 +++++++++++++++ .../danglingAnnotationsFileLevel.kt | 1 + ...anglingAnnotationsFileLevel.lazyBodies.txt | 2 + .../danglingAnnotationsFileLevel.txt | 2 + ...FirBuilderLazyBodiesTestCaseGenerated.java | 10 +++ .../RawFirBuilderTestCaseGenerated.java | 10 +++ .../kotlin/fir/builder/BaseFirBuilder.kt | 5 +- .../declarations/FirDanglingModifierList.kt | 43 +++++++++++++ .../builder/FirDanglingModifierListBuilder.kt | 63 ++++++++++++++++++ .../impl/FirDanglingModifierListImpl.kt | 64 +++++++++++++++++++ .../kotlin/fir/visitors/FirDefaultVisitor.kt | 1 + .../fir/visitors/FirDefaultVisitorVoid.kt | 1 + .../kotlin/fir/visitors/FirTransformer.kt | 9 +++ .../kotlin/fir/visitors/FirVisitor.kt | 3 + .../kotlin/fir/visitors/FirVisitorVoid.kt | 9 +++ .../org/jetbrains/kotlin/fir/ClassMembers.kt | 4 ++ .../fir/diagnostics/ConeSimpleDiagnostic.kt | 5 ++ .../kotlin/fir/renderer/FirRenderer.kt | 5 ++ .../symbols/impl/FirDanglingModifierSymbol.kt | 13 ++++ .../fir/tree/generator/FirTreeBuilder.kt | 1 + .../generator/ImplementationConfigurator.kt | 1 + .../fir/tree/generator/NodeConfigurator.kt | 4 ++ .../org/jetbrains/kotlin/KtSourceElement.kt | 3 + .../tests/annotations/DanglingMixed.fir.kt | 22 ------- .../tests/annotations/DanglingMixed.kt | 9 ++- .../tests/annotations/DanglingMixed.txt | 7 ++ .../FirVisualizerForRawFirDataGenerated.java | 12 ++++ .../PsiVisualizerForRawFirDataGenerated.java | 12 ++++ 70 files changed, 895 insertions(+), 48 deletions(-) create mode 100644 analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt create mode 100644 analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.txt create mode 100644 analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt create mode 100644 analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.txt create mode 100644 analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt create mode 100644 analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.txt create mode 100644 analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt create mode 100644 analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.txt create mode 100644 analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt create mode 100644 analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationClassLevel.kt create mode 100644 analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationTopLevel.kt create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotation.kt create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotation.txt create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotationInClass.kt create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotationInClass.txt create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/secondaryConstructor.kt create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/secondaryConstructor.txt create mode 100644 compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt create mode 100644 compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.lazyBodies.txt create mode 100644 compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.txt create mode 100644 compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt create mode 100644 compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.lazyBodies.txt create mode 100644 compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.txt create mode 100644 compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDanglingModifierList.kt create mode 100644 compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirDanglingModifierListBuilder.kt create mode 100644 compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDanglingModifierListImpl.kt create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirDanglingModifierSymbol.kt delete mode 100644 compiler/testData/diagnostics/tests/annotations/DanglingMixed.fir.kt diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java index d4df6f21455..4b586d1daad 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/references/Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -718,6 +718,40 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte } } + @Nested + @TestMetadata("analysis/analysis-api/testData/referenceResolve/danglingAnnotations") + @TestDataPath("$PROJECT_ROOT") + public class DanglingAnnotations { + @Test + public void testAllFilesPresentInDanglingAnnotations() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/danglingAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedAnonymous.kt") + public void testDanglingAnnotationsResolvedAnonymous() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedClass.kt") + public void testDanglingAnnotationsResolvedClass() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedLocal.kt") + public void testDanglingAnnotationsResolvedLocal() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedTopLevel.kt") + public void testDanglingAnnotationsResolvedTopLevel() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt"); + } + } + @Nested @TestMetadata("analysis/analysis-api/testData/referenceResolve/delegatedPropertyAccessors") @TestDataPath("$PROJECT_ROOT") @@ -1609,6 +1643,12 @@ public class Fe10IdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exte runTest("analysis/analysis-api/testData/referenceResolve/withErrors/CoroutineSuspensionPoint.kt"); } + @Test + @TestMetadata("DanglingAnnotations.kt") + public void testDanglingAnnotations() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt"); + } + @Test @TestMetadata("DeprecatedHidden.kt") public void testDeprecatedHidden() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java index cdaba2aeca0..994cd1ce0eb 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -718,6 +718,40 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex } } + @Nested + @TestMetadata("analysis/analysis-api/testData/referenceResolve/danglingAnnotations") + @TestDataPath("$PROJECT_ROOT") + public class DanglingAnnotations { + @Test + public void testAllFilesPresentInDanglingAnnotations() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/danglingAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedAnonymous.kt") + public void testDanglingAnnotationsResolvedAnonymous() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedClass.kt") + public void testDanglingAnnotationsResolvedClass() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedLocal.kt") + public void testDanglingAnnotationsResolvedLocal() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedTopLevel.kt") + public void testDanglingAnnotationsResolvedTopLevel() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt"); + } + } + @Nested @TestMetadata("analysis/analysis-api/testData/referenceResolve/delegatedPropertyAccessors") @TestDataPath("$PROJECT_ROOT") @@ -1609,6 +1643,12 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex runTest("analysis/analysis-api/testData/referenceResolve/withErrors/CoroutineSuspensionPoint.kt"); } + @Test + @TestMetadata("DanglingAnnotations.kt") + public void testDanglingAnnotations() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt"); + } + @Test @TestMetadata("DeprecatedHidden.kt") public void testDeprecatedHidden() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerated.java index 49a93c84ec1..747219ba8fd 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerated.java @@ -690,6 +690,40 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate } } + @Nested + @TestMetadata("analysis/analysis-api/testData/referenceResolve/danglingAnnotations") + @TestDataPath("$PROJECT_ROOT") + public class DanglingAnnotations { + @Test + public void testAllFilesPresentInDanglingAnnotations() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/danglingAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), null, true, "withErrors"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedAnonymous.kt") + public void testDanglingAnnotationsResolvedAnonymous() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedClass.kt") + public void testDanglingAnnotationsResolvedClass() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedLocal.kt") + public void testDanglingAnnotationsResolvedLocal() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedTopLevel.kt") + public void testDanglingAnnotationsResolvedTopLevel() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt"); + } + } + @Nested @TestMetadata("analysis/analysis-api/testData/referenceResolve/delegatedPropertyAccessors") @TestDataPath("$PROJECT_ROOT") diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java index 6bc12e2348e..4b1d3c0cea1 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -718,6 +718,40 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten } } + @Nested + @TestMetadata("analysis/analysis-api/testData/referenceResolve/danglingAnnotations") + @TestDataPath("$PROJECT_ROOT") + public class DanglingAnnotations { + @Test + public void testAllFilesPresentInDanglingAnnotations() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/danglingAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedAnonymous.kt") + public void testDanglingAnnotationsResolvedAnonymous() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedClass.kt") + public void testDanglingAnnotationsResolvedClass() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedLocal.kt") + public void testDanglingAnnotationsResolvedLocal() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedTopLevel.kt") + public void testDanglingAnnotationsResolvedTopLevel() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt"); + } + } + @Nested @TestMetadata("analysis/analysis-api/testData/referenceResolve/delegatedPropertyAccessors") @TestDataPath("$PROJECT_ROOT") @@ -1609,6 +1643,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten runTest("analysis/analysis-api/testData/referenceResolve/withErrors/CoroutineSuspensionPoint.kt"); } + @Test + @TestMetadata("DanglingAnnotations.kt") + public void testDanglingAnnotations() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt"); + } + @Test @TestMetadata("DeprecatedHidden.kt") public void testDeprecatedHidden() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java index d229fe50e18..23d2a067283 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerated.java @@ -718,6 +718,40 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate } } + @Nested + @TestMetadata("analysis/analysis-api/testData/referenceResolve/danglingAnnotations") + @TestDataPath("$PROJECT_ROOT") + public class DanglingAnnotations { + @Test + public void testAllFilesPresentInDanglingAnnotations() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/referenceResolve/danglingAnnotations"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedAnonymous.kt") + public void testDanglingAnnotationsResolvedAnonymous() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedClass.kt") + public void testDanglingAnnotationsResolvedClass() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedLocal.kt") + public void testDanglingAnnotationsResolvedLocal() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt"); + } + + @Test + @TestMetadata("DanglingAnnotationsResolvedTopLevel.kt") + public void testDanglingAnnotationsResolvedTopLevel() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt"); + } + } + @Nested @TestMetadata("analysis/analysis-api/testData/referenceResolve/delegatedPropertyAccessors") @TestDataPath("$PROJECT_ROOT") @@ -1609,6 +1643,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceResolveTestGenerate runTest("analysis/analysis-api/testData/referenceResolve/withErrors/CoroutineSuspensionPoint.kt"); } + @Test + @TestMetadata("DanglingAnnotations.kt") + public void testDanglingAnnotations() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt"); + } + @Test @TestMetadata("DeprecatedHidden.kt") public void testDeprecatedHidden() throws Exception { diff --git a/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt new file mode 100644 index 00000000000..e83f7f7a1b5 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.kt @@ -0,0 +1,10 @@ +// COMPILATION_ERRORS +annotation class Ann0 +interface I +class Foo { + fun foo() { + val i = object : I { + @Ann0 @Suppress + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.txt b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.txt new file mode 100644 index 00000000000..26a0a77419c --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedAnonymous.txt @@ -0,0 +1,2 @@ +Resolved to: +0: (in Ann0) constructor() diff --git a/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt new file mode 100644 index 00000000000..f19134b348e --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.kt @@ -0,0 +1,6 @@ +// COMPILATION_ERRORS +annotation class Ann0 +interface I +class Foo { + @Ann0 @Suppress +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.txt b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.txt new file mode 100644 index 00000000000..26a0a77419c --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedClass.txt @@ -0,0 +1,2 @@ +Resolved to: +0: (in Ann0) constructor() diff --git a/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt new file mode 100644 index 00000000000..7ae20dacbd0 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.kt @@ -0,0 +1,9 @@ +// COMPILATION_ERRORS +annotation class Ann0 +class Foo { + fun foo() { + class Local { + @Ann0 @Suppress + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.txt b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.txt new file mode 100644 index 00000000000..26a0a77419c --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedLocal.txt @@ -0,0 +1,2 @@ +Resolved to: +0: (in Ann0) constructor() diff --git a/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt new file mode 100644 index 00000000000..4f8267fb68d --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.kt @@ -0,0 +1,3 @@ +// COMPILATION_ERRORS +annotation class Ann0 +@Ann0 @Suppress diff --git a/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.txt b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.txt new file mode 100644 index 00000000000..26a0a77419c --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/danglingAnnotations/DanglingAnnotationsResolvedTopLevel.txt @@ -0,0 +1,2 @@ +Resolved to: +0: (in Ann0) constructor() diff --git a/analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt b/analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt new file mode 100644 index 00000000000..624aefc7a76 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/withErrors/DanglingAnnotations.kt @@ -0,0 +1,8 @@ +// UNRESOLVED_REFERENCE +class Foo { + fun foo() { + class Local { + @Ann0 + } + } +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDesignation.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDesignation.kt index c03997b1fa8..75521ec8230 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDesignation.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/api/FirDesignation.kt @@ -18,11 +18,15 @@ import org.jetbrains.kotlin.fir.containingClassLookupTag import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.declarations.utils.isLocal -import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel import org.jetbrains.kotlin.fir.java.javaSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol +import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment +import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder +import org.jetbrains.kotlin.fir.containingClass +import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel +import org.jetbrains.kotlin.fir.java.javaSymbolProvider class FirDesignationWithFile( path: List, @@ -92,6 +96,11 @@ private fun collectDesignationPath(target: FirElementWithResolvePhase): List { + val klass = target.containingClass() ?: return emptyList() + if (klass.classId.isLocal) return null + klass.toFirRegularClassFromSameSession(target.moduleData.session) + } else -> return null } ?: return emptyList() diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt index a71fb71ba7d..ebe8aabd211 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostics/fir/ContextCollectingDiagnosticCollectorVisitor.kt @@ -12,10 +12,8 @@ import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElementWithResolvePhase import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor -import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration -import org.jetbrains.kotlin.fir.declarations.FirDeclaration -import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.containingClass +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.resolve.SessionHolder @@ -61,6 +59,7 @@ internal object PersistenceContextCollector { val isLocal = when (declaration) { is FirClassLikeDeclaration -> declaration.symbol.classId.isLocal is FirCallableDeclaration -> declaration.symbol.callableId.isLocal + is FirDanglingModifierList -> declaration.containingClass()?.classId?.isLocal == true else -> error("Unsupported declaration ${declaration.renderWithType()}") } require(!isLocal) { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt index 9cf791bd952..fc34d9f618f 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructure.kt @@ -6,12 +6,17 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure import com.intellij.psi.PsiElement +import com.intellij.psi.PsiErrorElement +import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration +import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries +import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceByTraversingWholeTree import org.jetbrains.kotlin.analysis.low.level.api.fir.util.findSourceNonLocalFirDeclaration import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic +import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.resolve.providers.firProvider @@ -36,14 +41,23 @@ internal class FileStructure private constructor( private val firProvider = firFile.moduleData.session.firProvider - private val structureElements = ConcurrentHashMap() + private val structureElements = ConcurrentHashMap() fun getStructureElementFor(element: KtElement): FileStructureElement { - val container: KtAnnotated = element.getNonLocalContainingOrThisDeclaration() ?: element.containingKtFile + val declaration = element.getNonLocalContainingOrThisDeclaration() + val container: KtElement + if (declaration != null) { + container = declaration + } else { + val modifierList = PsiTreeUtil.getParentOfType(element, KtModifierList::class.java, false) + container = if (modifierList != null && modifierList.nextSibling is PsiErrorElement) { + modifierList + } else element.containingKtFile + } return getStructureElementForDeclaration(container) } - private fun getStructureElementForDeclaration(declaration: KtAnnotated): FileStructureElement { + private fun getStructureElementForDeclaration(declaration: KtElement): FileStructureElement { @Suppress("CANNOT_CHECK_FOR_ERASED") val structureElement = structureElements.compute(declaration) { _, structureElement -> when { @@ -91,6 +105,12 @@ internal class FileStructure private constructor( dcl.acceptChildren(this) } } + + override fun visitModifierList(list: KtModifierList) { + if (list.parent == ktFile) { + structureElements += getStructureElementFor(list) + } + } }) return structureElements @@ -112,8 +132,15 @@ internal class FileStructure private constructor( ) } - private fun createStructureElement(container: KtAnnotated): FileStructureElement = when (container) { - is KtFile -> { + private fun createDanglingModifierListStructure(container: KtElement): FileStructureElement { + val firDanglingModifierList = container.findSourceByTraversingWholeTree(moduleComponents.firFileBuilder, firFile) as? FirDanglingModifierList + ?: errorWithFirSpecificEntries("No dangling modifier found", psi = container) + firDanglingModifierList.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) + return DanglingTopLevelModifierListStructureElement(firFile, firDanglingModifierList, moduleComponents, container.containingKtFile) + } + + private fun createStructureElement(container: KtElement): FileStructureElement = when { + container is KtFile -> { val firFile = moduleComponents.firFileBuilder.buildRawFirFileWithCaching(ktFile) moduleComponents.firModuleLazyDeclarationResolver.lazyResolve( target = firFile.annotationsContainer, @@ -123,7 +150,8 @@ internal class FileStructure private constructor( RootStructureElement(firFile, container, moduleComponents) } - is KtDeclaration -> createDeclarationStructure(container) + container is KtDeclaration -> createDeclarationStructure(container) + container is KtModifierList && container.nextSibling is PsiErrorElement -> createDanglingModifierListStructure(container) else -> error("Invalid container $container") } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureElement.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureElement.kt index 7a813079c06..23fa2530caf 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureElement.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureElement.kt @@ -226,6 +226,12 @@ internal class NonReanalyzableDeclarationStructureElement( } } +internal class DanglingTopLevelModifierListStructureElement(firFile: FirFile, val fir: FirDeclaration, moduleComponents: LLFirModuleResolveComponents, override val psi: KtAnnotated) : + FileStructureElement(firFile, moduleComponents) { + override val mappings = KtToFirMapping(fir, FirElementsRecorder()) + + override val diagnostics = FileStructureElementDiagnostics(firFile, SingleNonLocalDeclarationDiagnosticRetriever(fir), moduleComponents) +} internal class RootStructureElement( firFile: FirFile, @@ -246,4 +252,4 @@ internal class RootStructureElement( } } } -} +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FirElementsRecorder.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FirElementsRecorder.kt index aa0dd301e09..961a03bdf0a 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FirElementsRecorder.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FirElementsRecorder.kt @@ -116,6 +116,7 @@ internal open class FirElementsRecorder : FirVisitor containingFunctionSymbol.fir.getContainingFile() is FirCallableDeclaration -> provider.getFirCallableContainerFile(symbol) is FirClassLikeDeclaration -> provider.getFirClassifierContainerFile(symbol) + is FirDanglingModifierList -> null else -> errorWithFirSpecificEntries("Unsupported declaration ${this::class.java}", fir = this) } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt index 746de889c7e..719dcb114c8 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt @@ -28,7 +28,7 @@ internal fun KtDeclaration.findSourceNonLocalFirDeclaration( ): FirDeclaration { //TODO test what way faster findSourceNonLocalFirDeclarationByProvider(firFileBuilder, provider, containerFirFile)?.let { return it } - findSourceOfNonLocalFirDeclarationByTraversingWholeTree(firFileBuilder, containerFirFile)?.let { return it } + findSourceByTraversingWholeTree(firFileBuilder, containerFirFile)?.let { return it } errorWithFirSpecificEntries("No fir element was found for", psi = this) } @@ -56,14 +56,15 @@ internal inline fun KtDeclaration.findFirDeclaratio return fir } -private fun KtDeclaration.findSourceOfNonLocalFirDeclarationByTraversingWholeTree( +internal fun KtElement.findSourceByTraversingWholeTree( firFileBuilder: LLFirFileBuilder, containerFirFile: FirFile?, ): FirDeclaration? { val firFile = containerFirFile ?: firFileBuilder.buildRawFirFileWithCaching(containingKtFile) - val originalDeclaration = originalDeclaration + val originalDeclaration = (this as? KtDeclaration)?.originalDeclaration + val isDeclaration = this is KtDeclaration return FirElementFinder.findElementIn(firFile, canGoInside = { it is FirRegularClass }) { firDeclaration -> - firDeclaration.psi == this || firDeclaration.psi == originalDeclaration + firDeclaration.psi == this || isDeclaration && firDeclaration.psi == originalDeclaration } } diff --git a/analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationClassLevel.kt b/analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationClassLevel.kt new file mode 100644 index 00000000000..9ccf19d03e3 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationClassLevel.kt @@ -0,0 +1,16 @@ +class Foo {/* NonReanalyzableDeclarationStructureElement */ + @Suppress("") @MustBeDocumented +} +class Bar {/* NonReanalyzableDeclarationStructureElement */ + @Suppress("") @MustBeDocumented +} +class Outer {/* NonReanalyzableDeclarationStructureElement */ + class Inner {/* NonReanalyzableDeclarationStructureElement */ + @Suppress("") @MustBeDocumented + } + fun foo() {/* ReanalyzableFunctionStructureElement */ + class Local { + @Suppress("") @MustBeDocumented + } + } +} diff --git a/analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationTopLevel.kt b/analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationTopLevel.kt new file mode 100644 index 00000000000..dd22e44a5ff --- /dev/null +++ b/analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationTopLevel.kt @@ -0,0 +1 @@ +@Suppress("") @MustBeDocumented/* DanglingTopLevelModifierListStructureElement */ diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotation.kt b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotation.kt new file mode 100644 index 00000000000..4bd66a66434 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotation.kt @@ -0,0 +1,3 @@ +// WITH_STDLIB +// LOOK_UP_FOR_ELEMENT_OF_TYPE: org.jetbrains.kotlin.psi.KtAnnotationEntry +@Suppress("") @MustBeDocumented \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotation.txt b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotation.txt new file mode 100644 index 00000000000..8e4d5fb285d --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotation.txt @@ -0,0 +1,6 @@ +KT element: KtAnnotationEntry +FIR element: FirAnnotationCallImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +@R|kotlin/Suppress|(names = vararg(String())) \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotationInClass.kt b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotationInClass.kt new file mode 100644 index 00000000000..ee93e285d5c --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotationInClass.kt @@ -0,0 +1,5 @@ +// WITH_STDLIB +// LOOK_UP_FOR_ELEMENT_OF_TYPE: org.jetbrains.kotlin.psi.KtAnnotationEntry +class F { + @Suppress("") @MustBeDocumented +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotationInClass.txt b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotationInClass.txt new file mode 100644 index 00000000000..8e4d5fb285d --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotationInClass.txt @@ -0,0 +1,6 @@ +KT element: KtAnnotationEntry +FIR element: FirAnnotationCallImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +@R|kotlin/Suppress|(names = vararg(String())) \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/secondaryConstructor.kt b/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/secondaryConstructor.kt new file mode 100644 index 00000000000..2de5af7b656 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/secondaryConstructor.kt @@ -0,0 +1,5 @@ +annotation class JsQualifier : kotlin.Annotation { + public constructor JsQualifier(value: kotlin.String) + + public final val value: kotlin.String { get; } +} diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/secondaryConstructor.txt b/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/secondaryConstructor.txt new file mode 100644 index 00000000000..79024476467 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/secondaryConstructor.txt @@ -0,0 +1,6 @@ +KT element: KtDeclarationModifierList +FIR element: FirDanglingModifierListImpl +FIR source kind: DanglingModifierList + +FIR element rendered: + \ No newline at end of file diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirLazyBodiesCalculatorTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirLazyBodiesCalculatorTestGenerated.java index bc306a060ab..ec5e9894861 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirLazyBodiesCalculatorTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirLazyBodiesCalculatorTestGenerated.java @@ -75,6 +75,18 @@ public class FirLazyBodiesCalculatorTestGenerated extends AbstractFirLazyBodiesC runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt"); } + @Test + @TestMetadata("danglingAnnotationsClassLevel.kt") + public void testDanglingAnnotationsClassLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt"); + } + + @Test + @TestMetadata("danglingAnnotationsFileLevel.kt") + public void testDanglingAnnotationsFileLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt"); + } + @Test @TestMetadata("delegates.kt") public void testDelegates() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java index dd077b1bcc4..7c62ac0e11f 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/GetOrBuildFirTestGenerated.java @@ -69,6 +69,18 @@ public class GetOrBuildFirTestGenerated extends AbstractGetOrBuildFirTest { runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/annotationApplicationWithArgumentsOnCallSite.kt"); } + @Test + @TestMetadata("danglingAnnotation.kt") + public void testDanglingAnnotation() throws Exception { + runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotation.kt"); + } + + @Test + @TestMetadata("danglingAnnotationInClass.kt") + public void testDanglingAnnotationInClass() throws Exception { + runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/annotations/danglingAnnotationInClass.kt"); + } + @Test @TestMetadata("fileAnnotation.kt") public void testFileAnnotation() throws Exception { @@ -572,6 +584,12 @@ public class GetOrBuildFirTestGenerated extends AbstractGetOrBuildFirTest { public void testJavaClassLiteral() throws Exception { runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/javaClassLiteral.kt"); } + + @Test + @TestMetadata("secondaryConstructor.kt") + public void testSecondaryConstructor() throws Exception { + runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/secondaryConstructor.kt"); + } } @Nested diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/AbstractFirContextCollectionTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/AbstractFirContextCollectionTest.kt index c6cd958677b..6d39078d742 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/AbstractFirContextCollectionTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/AbstractFirContextCollectionTest.kt @@ -17,6 +17,8 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getDiagnostics import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.BeforeElementDiagnosticCollectionHandler import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.fir.PersistenceContextCollector +import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.* +import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.DanglingTopLevelModifierListStructureElement import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.FileStructureElement import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.NonReanalyzableDeclarationStructureElement import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.ReanalyzableStructureElement @@ -62,6 +64,7 @@ abstract class AbstractFirContextCollectionTest : AbstractLowLevelApiSingleFileT is NonReanalyzableDeclarationStructureElement -> fir is ReanalyzableStructureElement<*, *> -> firSymbol.fir is RootStructureElement -> firFile + is DanglingTopLevelModifierListStructureElement -> fir } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/FirContextCollectionTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/FirContextCollectionTestGenerated.java index 4f67dc43c9a..0285f6107e8 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/FirContextCollectionTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/FirContextCollectionTestGenerated.java @@ -36,6 +36,18 @@ public class FirContextCollectionTestGenerated extends AbstractFirContextCollect runTest("analysis/low-level-api-fir/testdata/fileStructure/classMemberProperty.kt"); } + @Test + @TestMetadata("danglingAnnotationClassLevel.kt") + public void testDanglingAnnotationClassLevel() throws Exception { + runTest("analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationClassLevel.kt"); + } + + @Test + @TestMetadata("danglingAnnotationTopLevel.kt") + public void testDanglingAnnotationTopLevel() throws Exception { + runTest("analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationTopLevel.kt"); + } + @Test @TestMetadata("declarationsInPropertyInit.kt") public void testDeclarationsInPropertyInit() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/AbstractFileStructureTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/AbstractFileStructureTest.kt index c31119d1b9d..c1ff8a67279 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/AbstractFileStructureTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/AbstractFileStructureTest.kt @@ -8,7 +8,9 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure import com.intellij.psi.PsiComment import com.intellij.psi.PsiElement import com.intellij.psi.PsiElementVisitor +import com.intellij.psi.PsiErrorElement import com.intellij.psi.impl.source.tree.LeafPsiElement +import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirSourceResolveSession import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getFirResolveSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession @@ -32,7 +34,8 @@ abstract class AbstractFileStructureTest : AbstractLowLevelApiSingleFileTest() { val comment = structureElement.createComment() when (ktDeclaration) { is KtClassOrObject -> { - val lBrace = ktDeclaration.body?.lBrace + val body = ktDeclaration.body + val lBrace = body?.lBrace if (lBrace != null) { elementToComment[lBrace] = comment } else { @@ -62,6 +65,13 @@ abstract class AbstractFileStructureTest : AbstractLowLevelApiSingleFileTest() { } } + PsiTreeUtil.getChildrenOfTypeAsList(ktFile, KtModifierList::class.java).forEach { + if (it.nextSibling is PsiErrorElement) { + val structureElement = declarationToStructureElement[ktFile] ?: return@forEach + val comment = structureElement.createComment() + elementToComment[it] = comment + } + } val text = buildString { ktFile.accept(object : PsiElementVisitor() { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureTestGenerated.java index 7ff903b4237..db31d9574a9 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureTestGenerated.java @@ -36,6 +36,18 @@ public class FileStructureTestGenerated extends AbstractFileStructureTest { runTest("analysis/low-level-api-fir/testdata/fileStructure/classMemberProperty.kt"); } + @Test + @TestMetadata("danglingAnnotationClassLevel.kt") + public void testDanglingAnnotationClassLevel() throws Exception { + runTest("analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationClassLevel.kt"); + } + + @Test + @TestMetadata("danglingAnnotationTopLevel.kt") + public void testDanglingAnnotationTopLevel() throws Exception { + runTest("analysis/low-level-api-fir/testdata/fileStructure/danglingAnnotationTopLevel.kt"); + } + @Test @TestMetadata("declarationsInPropertyInit.kt") public void testDeclarationsInPropertyInit() throws Exception { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt index df7a8899c6c..51d66580afc 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageBaseChecker.kt @@ -154,7 +154,7 @@ object FirOptInUsageBaseChecker { fir.loadCallableSpecificExperimentalities(this, context, visited, fromSetter, dispatchReceiverType, result) is FirClassLikeDeclaration -> fir.loadClassLikeSpecificExperimentalities(this, context, visited, result) - is FirAnonymousInitializer, is FirFile, is FirTypeParameter, is FirScript -> {} + is FirAnonymousInitializer, is FirDanglingModifierList, is FirFile, is FirTypeParameter, is FirScript -> {} } fir.loadExperimentalitiesFromAnnotationTo(session, result, fromSupertype) diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 9a64c8a20b0..7d5fddd0cda 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.* import org.jetbrains.kotlin.fir.declarations.impl.* import org.jetbrains.kotlin.fir.declarations.utils.* +import org.jetbrains.kotlin.fir.diagnostics.ConeDanglingModifierOnTopLevel import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind @@ -97,6 +98,7 @@ class DeclarationsConverter( var fileAnnotationContainer: FirFileAnnotationsContainer? = null val importList = mutableListOf() val firDeclarationList = mutableListOf() + val modifierList = mutableListOf() context.packageFqName = FqName.ROOT var packageDirective: FirPackageDirective? = null file.forEachChildren { child -> @@ -116,9 +118,14 @@ class DeclarationsConverter( SCRIPT -> { // TODO: scripts aren't supported yet } + MODIFIER_LIST -> modifierList += child } } + modifierList.forEach { + firDeclarationList += buildErrorTopLevelDeclarationForDanglingModifierList(it) + } + return buildFile { symbol = fileSymbol source = file.toFirSourceElement() @@ -839,7 +846,8 @@ class DeclarationsConverter( * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseEnumClassBody */ private fun convertClassBody(classBody: LighterASTNode, classWrapper: ClassWrapper): List { - return classBody.forEachChildrenReturnList { node, container -> + val modifierLists = mutableListOf() + var firDeclarations = classBody.forEachChildrenReturnList { node, container -> @Suppress("RemoveRedundantQualifierName") when (node.tokenType) { ENUM_ENTRY -> container += convertEnumEntry(node, classWrapper) @@ -850,8 +858,22 @@ class DeclarationsConverter( OBJECT_DECLARATION -> container += convertClass(node) CLASS_INITIALIZER -> container += convertAnonymousInitializer(node) //anonymousInitializer SECONDARY_CONSTRUCTOR -> container += convertSecondaryConstructor(node, classWrapper) + MODIFIER_LIST -> modifierLists += node } } + for (node in modifierLists) { + firDeclarations += buildErrorTopLevelDeclarationForDanglingModifierList(node) + } + return firDeclarations + } + + private fun buildErrorTopLevelDeclarationForDanglingModifierList(node: LighterASTNode) = buildDanglingModifierList { + this.source = node.toFirSourceElement(KtFakeSourceElementKind.DanglingModifierList) + moduleData = baseModuleData + origin = FirDeclarationOrigin.Source + diagnostic = ConeDanglingModifierOnTopLevel + symbol = FirDanglingModifierSymbol() + annotations += convertModifierList(node).annotations } /** diff --git a/compiler/fir/raw-fir/light-tree2fir/tests-gen/org/jetbrains/kotlin/fir/lightTree/LightTree2FirConverterTestCaseGenerated.java b/compiler/fir/raw-fir/light-tree2fir/tests-gen/org/jetbrains/kotlin/fir/lightTree/LightTree2FirConverterTestCaseGenerated.java index f69cb9ab9e6..8408ed105ff 100644 --- a/compiler/fir/raw-fir/light-tree2fir/tests-gen/org/jetbrains/kotlin/fir/lightTree/LightTree2FirConverterTestCaseGenerated.java +++ b/compiler/fir/raw-fir/light-tree2fir/tests-gen/org/jetbrains/kotlin/fir/lightTree/LightTree2FirConverterTestCaseGenerated.java @@ -76,6 +76,16 @@ public class LightTree2FirConverterTestCaseGenerated extends AbstractLightTree2F runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt"); } + @TestMetadata("danglingAnnotationsClassLevel.kt") + public void testDanglingAnnotationsClassLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt"); + } + + @TestMetadata("danglingAnnotationsFileLevel.kt") + public void testDanglingAnnotationsFileLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt"); + } + @TestMetadata("delegates.kt") public void testDelegates() throws Exception { runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/delegates.kt"); diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 7a4fc04854a..046669ac088 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.builder import com.intellij.psi.PsiElement import com.intellij.psi.tree.IElementType import com.intellij.util.AstLoadingFilter +import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.* import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames.BACKING_FIELD @@ -1057,6 +1058,10 @@ open class RawFirBuilder( else -> declaration.convert() } } + + for (danglingModifierList in PsiTreeUtil.getChildrenOfTypeAsList(file, KtModifierList::class.java)) { + declarations += buildErrorTopLevelDeclarationForDanglingModifierList(danglingModifierList) + } } } @@ -1269,7 +1274,14 @@ open class RawFirBuilder( classOrObject, this, typeParameters - ), + ) + ) + } + for (danglingModifier in PsiTreeUtil.getChildrenOfTypeAsList(classOrObject.body, KtModifierList::class.java)) { + addDeclaration( + buildErrorTopLevelDeclarationForDanglingModifierList(danglingModifier).apply { + containingClassAttr = currentDispatchReceiverType()?.lookupTag + } ) } @@ -1361,6 +1373,12 @@ open class RawFirBuilder( ownerTypeParameters = emptyList() ) } + + for (danglingModifier in PsiTreeUtil.getChildrenOfTypeAsList(objectDeclaration.body, KtModifierList::class.java)) { + declarations += buildErrorTopLevelDeclarationForDanglingModifierList(danglingModifier).apply { + containingClassAttr = currentDispatchReceiverType()?.lookupTag + } + } }.also { it.delegateFieldsMap = delegatedFieldsMap } @@ -2730,6 +2748,17 @@ open class RawFirBuilder( this += typeArgument.convert() } } + + private fun buildErrorTopLevelDeclarationForDanglingModifierList(modifierList : KtModifierList) = buildDanglingModifierList { + this.source = modifierList.toFirSourceElement(KtFakeSourceElementKind.DanglingModifierList) + moduleData = baseModuleData + origin = FirDeclarationOrigin.Source + diagnostic = ConeDanglingModifierOnTopLevel + symbol = FirDanglingModifierSymbol() + for (annotationEntry in modifierList.getAnnotationEntries()) { + annotations += annotationEntry.convert() + } + } } } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt new file mode 100644 index 00000000000..8def9a67415 --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt @@ -0,0 +1,22 @@ +class A { + @Suppress("") @MustBeDocumented +} +class B { + @Suppress("") @MustBeDocumented +} +class Outer { + class Inner { + @Suppress("") @MustBeDocumented + } + + fun withLocal() { + class Local { + @Suppress("") @MustBeDocumented + } + + val r : I = object : I { + @Suppress("") @MustBeDocumented + } + } +} +interface I {} \ No newline at end of file diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.lazyBodies.txt new file mode 100644 index 00000000000..2c1c255872d --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.lazyBodies.txt @@ -0,0 +1,33 @@ +FILE: danglingAnnotationsClassLevel.kt + public? final? class A : R|kotlin/Any| { + public? constructor(): R|A| { + super() + } + + @Suppress(String()) @MustBeDocumented() + } + public? final? class B : R|kotlin/Any| { + public? constructor(): R|B| { + super() + } + + @Suppress(String()) @MustBeDocumented() + } + public? final? class Outer : R|kotlin/Any| { + public? constructor(): R|Outer| { + super() + } + + public? final? class Inner : R|kotlin/Any| { + public? constructor(): R|Outer.Inner| { + super() + } + + @Suppress(String()) @MustBeDocumented() + } + + public? final? fun withLocal(): R|kotlin/Unit| { LAZY_BLOCK } + + } + public? final? interface I : R|kotlin/Any| { + } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.txt new file mode 100644 index 00000000000..19f0346dcdc --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.txt @@ -0,0 +1,50 @@ +FILE: danglingAnnotationsClassLevel.kt + public? final? class A : R|kotlin/Any| { + public? [ContainingClassKey=A] constructor(): R|A| { + super() + } + + @Suppress(String()) @MustBeDocumented() + } + public? final? class B : R|kotlin/Any| { + public? [ContainingClassKey=B] constructor(): R|B| { + super() + } + + @Suppress(String()) @MustBeDocumented() + } + public? final? class Outer : R|kotlin/Any| { + public? [ContainingClassKey=Outer] constructor(): R|Outer| { + super() + } + + public? final? class Inner : R|kotlin/Any| { + public? [ContainingClassKey=Inner] constructor(): R|Outer.Inner| { + super() + } + + @Suppress(String()) @MustBeDocumented() + } + + public? final? fun withLocal(): R|kotlin/Unit| { + local final? [ContainingClassKey=Outer] class Local : R|kotlin/Any| { + public? [ContainingClassKey=Local] constructor(): R|Outer.Local| { + super() + } + + @Suppress(String()) @MustBeDocumented() + } + + lval r: I = object : I { + private [ContainingClassKey=] constructor(): R|| { + super<>() + } + + @Suppress(String()) @MustBeDocumented() + } + + } + + } + public? final? interface I : R|kotlin/Any| { + } diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt new file mode 100644 index 00000000000..25633870edb --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt @@ -0,0 +1 @@ +@Suppress("") @MustBeDocumented \ No newline at end of file diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.lazyBodies.txt new file mode 100644 index 00000000000..fb90000b5be --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.lazyBodies.txt @@ -0,0 +1,2 @@ +FILE: danglingAnnotationsFileLevel.kt + @Suppress(String()) @MustBeDocumented() \ No newline at end of file diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.txt new file mode 100644 index 00000000000..fb90000b5be --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.txt @@ -0,0 +1,2 @@ +FILE: danglingAnnotationsFileLevel.kt + @Suppress(String()) @MustBeDocumented() \ No newline at end of file diff --git a/compiler/fir/raw-fir/psi2fir/tests-gen/org/jetbrains/kotlin/fir/builder/RawFirBuilderLazyBodiesTestCaseGenerated.java b/compiler/fir/raw-fir/psi2fir/tests-gen/org/jetbrains/kotlin/fir/builder/RawFirBuilderLazyBodiesTestCaseGenerated.java index a8c12dbdf32..ab99172010e 100644 --- a/compiler/fir/raw-fir/psi2fir/tests-gen/org/jetbrains/kotlin/fir/builder/RawFirBuilderLazyBodiesTestCaseGenerated.java +++ b/compiler/fir/raw-fir/psi2fir/tests-gen/org/jetbrains/kotlin/fir/builder/RawFirBuilderLazyBodiesTestCaseGenerated.java @@ -76,6 +76,16 @@ public class RawFirBuilderLazyBodiesTestCaseGenerated extends AbstractRawFirBuil runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt"); } + @TestMetadata("danglingAnnotationsClassLevel.kt") + public void testDanglingAnnotationsClassLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt"); + } + + @TestMetadata("danglingAnnotationsFileLevel.kt") + public void testDanglingAnnotationsFileLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt"); + } + @TestMetadata("delegates.kt") public void testDelegates() throws Exception { runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/delegates.kt"); diff --git a/compiler/fir/raw-fir/psi2fir/tests-gen/org/jetbrains/kotlin/fir/builder/RawFirBuilderTestCaseGenerated.java b/compiler/fir/raw-fir/psi2fir/tests-gen/org/jetbrains/kotlin/fir/builder/RawFirBuilderTestCaseGenerated.java index 6de3f44d522..c18d6a0587a 100644 --- a/compiler/fir/raw-fir/psi2fir/tests-gen/org/jetbrains/kotlin/fir/builder/RawFirBuilderTestCaseGenerated.java +++ b/compiler/fir/raw-fir/psi2fir/tests-gen/org/jetbrains/kotlin/fir/builder/RawFirBuilderTestCaseGenerated.java @@ -76,6 +76,16 @@ public class RawFirBuilderTestCaseGenerated extends AbstractRawFirBuilderTestCas runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt"); } + @TestMetadata("danglingAnnotationsClassLevel.kt") + public void testDanglingAnnotationsClassLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt"); + } + + @TestMetadata("danglingAnnotationsFileLevel.kt") + public void testDanglingAnnotationsFileLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt"); + } + @TestMetadata("delegates.kt") public void testDelegates() throws Exception { runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/delegates.kt"); diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index 0fd72a9ece6..046299c2a25 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -18,10 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.utils.addDeclaration import org.jetbrains.kotlin.fir.declarations.utils.isCompanion import org.jetbrains.kotlin.fir.declarations.utils.isLocal -import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel -import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic -import org.jetbrains.kotlin.fir.diagnostics.ConeUnderscoreIsReserved -import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind +import org.jetbrains.kotlin.fir.diagnostics.* import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.* import org.jetbrains.kotlin.fir.references.FirReference diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDanglingModifierList.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDanglingModifierList.kt new file mode 100644 index 00000000000..e526952edcd --- /dev/null +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirDanglingModifierList.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2022 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. + */ + +package org.jetbrains.kotlin.fir.declarations + +import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.FirModuleData +import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder +import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.symbols.impl.FirDanglingModifierSymbol +import org.jetbrains.kotlin.fir.visitors.* + +/* + * This file was generated automatically + * DO NOT MODIFY IT MANUALLY + */ + +abstract class FirDanglingModifierList : FirDeclaration(), FirDiagnosticHolder { + abstract override val source: KtSourceElement? + abstract override val resolvePhase: FirResolvePhase + abstract override val annotations: List + abstract override val moduleData: FirModuleData + abstract override val origin: FirDeclarationOrigin + abstract override val attributes: FirDeclarationAttributes + abstract override val diagnostic: ConeDiagnostic + abstract override val symbol: FirDanglingModifierSymbol + + override fun accept(visitor: FirVisitor, data: D): R = visitor.visitDanglingModifierList(this, data) + + @Suppress("UNCHECKED_CAST") + override fun transform(transformer: FirTransformer, data: D): E = + transformer.transformDanglingModifierList(this, data) as E + + abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) + + abstract override fun replaceAnnotations(newAnnotations: List) + + abstract override fun transformAnnotations(transformer: FirTransformer, data: D): FirDanglingModifierList +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirDanglingModifierListBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirDanglingModifierListBuilder.kt new file mode 100644 index 00000000000..75dad900626 --- /dev/null +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirDanglingModifierListBuilder.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2022 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. + */ + +@file:Suppress("DuplicatedCode") + +package org.jetbrains.kotlin.fir.declarations.builder + +import kotlin.contracts.* +import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.fir.FirModuleData +import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder +import org.jetbrains.kotlin.fir.builder.FirBuilderDsl +import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty +import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList +import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes +import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin +import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.declarations.impl.FirDanglingModifierListImpl +import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic +import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.symbols.impl.FirDanglingModifierSymbol +import org.jetbrains.kotlin.fir.visitors.* + +/* + * This file was generated automatically + * DO NOT MODIFY IT MANUALLY + */ + +@FirBuilderDsl +class FirDanglingModifierListBuilder : FirAnnotationContainerBuilder { + override var source: KtSourceElement? = null + var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR + override val annotations: MutableList = mutableListOf() + lateinit var moduleData: FirModuleData + lateinit var origin: FirDeclarationOrigin + var attributes: FirDeclarationAttributes = FirDeclarationAttributes() + lateinit var diagnostic: ConeDiagnostic + lateinit var symbol: FirDanglingModifierSymbol + + override fun build(): FirDanglingModifierList { + return FirDanglingModifierListImpl( + source, + resolvePhase, + annotations.toMutableOrEmpty(), + moduleData, + origin, + attributes, + diagnostic, + symbol, + ) + } + +} + +@OptIn(ExperimentalContracts::class) +inline fun buildDanglingModifierList(init: FirDanglingModifierListBuilder.() -> Unit): FirDanglingModifierList { + contract { + callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE) + } + return FirDanglingModifierListBuilder().apply(init).build() +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDanglingModifierListImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDanglingModifierListImpl.kt new file mode 100644 index 00000000000..d2a2ac90d70 --- /dev/null +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDanglingModifierListImpl.kt @@ -0,0 +1,64 @@ +/* + * Copyright 2010-2022 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. + */ + +@file:Suppress("DuplicatedCode") + +package org.jetbrains.kotlin.fir.declarations.impl + +import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.fir.FirModuleData +import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList +import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes +import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin +import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic +import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.fir.symbols.impl.FirDanglingModifierSymbol +import org.jetbrains.kotlin.fir.visitors.* +import org.jetbrains.kotlin.fir.MutableOrEmptyList +import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty + +/* + * This file was generated automatically + * DO NOT MODIFY IT MANUALLY + */ + +internal class FirDanglingModifierListImpl( + override val source: KtSourceElement?, + @Volatile + override var resolvePhase: FirResolvePhase, + override var annotations: MutableOrEmptyList, + override val moduleData: FirModuleData, + override val origin: FirDeclarationOrigin, + override val attributes: FirDeclarationAttributes, + override val diagnostic: ConeDiagnostic, + override val symbol: FirDanglingModifierSymbol, +) : FirDanglingModifierList() { + init { + symbol.bind(this) + } + + override fun acceptChildren(visitor: FirVisitor, data: D) { + annotations.forEach { it.accept(visitor, data) } + } + + override fun transformChildren(transformer: FirTransformer, data: D): FirDanglingModifierListImpl { + transformAnnotations(transformer, data) + return this + } + + override fun transformAnnotations(transformer: FirTransformer, data: D): FirDanglingModifierListImpl { + annotations.transformInplace(transformer, data) + return this + } + + override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) { + resolvePhase = newResolvePhase + } + + override fun replaceAnnotations(newAnnotations: List) { + annotations = newAnnotations.toMutableOrEmpty() + } +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt index 5701ef42347..6caff002a2d 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitor.kt @@ -95,6 +95,7 @@ import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirErrorExpression import org.jetbrains.kotlin.fir.declarations.FirErrorFunction import org.jetbrains.kotlin.fir.declarations.FirErrorProperty +import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedErrorAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt index ed42152af8e..002291e4203 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirDefaultVisitorVoid.kt @@ -95,6 +95,7 @@ import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirErrorExpression import org.jetbrains.kotlin.fir.declarations.FirErrorFunction import org.jetbrains.kotlin.fir.declarations.FirErrorProperty +import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedErrorAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt index 978d15473f4..28b05bcbbcf 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirTransformer.kt @@ -95,6 +95,7 @@ import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirErrorExpression import org.jetbrains.kotlin.fir.declarations.FirErrorFunction import org.jetbrains.kotlin.fir.declarations.FirErrorProperty +import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedErrorAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression @@ -514,6 +515,10 @@ abstract class FirTransformer : FirVisitor() { return transformElement(errorProperty, data) } + open fun transformDanglingModifierList(danglingModifierList: FirDanglingModifierList, data: D): FirDanglingModifierList { + return transformElement(danglingModifierList, data) + } + open fun transformQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: D): FirStatement { return transformElement(qualifiedAccessExpression, data) } @@ -1086,6 +1091,10 @@ abstract class FirTransformer : FirVisitor() { return transformErrorProperty(errorProperty, data) } + final override fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList, data: D): FirDanglingModifierList { + return transformDanglingModifierList(danglingModifierList, data) + } + final override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: D): FirStatement { return transformQualifiedAccessExpression(qualifiedAccessExpression, data) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt index 2405f45fa78..1df7a64e22b 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitor.kt @@ -95,6 +95,7 @@ import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirErrorExpression import org.jetbrains.kotlin.fir.declarations.FirErrorFunction import org.jetbrains.kotlin.fir.declarations.FirErrorProperty +import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedErrorAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression @@ -335,6 +336,8 @@ abstract class FirVisitor { open fun visitErrorProperty(errorProperty: FirErrorProperty, data: D): R = visitElement(errorProperty, data) + open fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList, data: D): R = visitElement(danglingModifierList, data) + open fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: D): R = visitElement(qualifiedAccessExpression, data) open fun visitQualifiedErrorAccessExpression(qualifiedErrorAccessExpression: FirQualifiedErrorAccessExpression, data: D): R = visitElement(qualifiedErrorAccessExpression, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt index 866eaa4fa02..06231ff03b3 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/visitors/FirVisitorVoid.kt @@ -95,6 +95,7 @@ import org.jetbrains.kotlin.fir.expressions.FirClassReferenceExpression import org.jetbrains.kotlin.fir.expressions.FirErrorExpression import org.jetbrains.kotlin.fir.declarations.FirErrorFunction import org.jetbrains.kotlin.fir.declarations.FirErrorProperty +import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedErrorAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression @@ -513,6 +514,10 @@ abstract class FirVisitorVoid : FirVisitor() { visitElement(errorProperty) } + open fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList) { + visitElement(danglingModifierList) + } + open fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression) { visitElement(qualifiedAccessExpression) } @@ -1085,6 +1090,10 @@ abstract class FirVisitorVoid : FirVisitor() { visitErrorProperty(errorProperty) } + final override fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList, data: Nothing?) { + visitDanglingModifierList(danglingModifierList) + } + final override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: Nothing?) { visitQualifiedAccessExpression(qualifiedAccessExpression) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/ClassMembers.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/ClassMembers.kt index b67b66ba25a..112a3d12a91 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/ClassMembers.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/ClassMembers.kt @@ -37,9 +37,13 @@ fun FirCallableDeclaration.containingClassLookupTag(): ConeClassLikeLookupTag? = fun FirRegularClass.containingClassForLocal(): ConeClassLikeLookupTag? = if (isLocal) containingClassForLocalAttr else null +fun FirDanglingModifierList.containingClass(): ConeClassLikeLookupTag? = + containingClassAttr + private object ContainingClassKey : FirDeclarationDataKey() var FirCallableDeclaration.containingClassForStaticMemberAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey) var FirRegularClass.containingClassForLocalAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey) +var FirDanglingModifierList.containingClassAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey) private object IsNewPlaceForBodyGeneration : FirDeclarationDataKey() var FirRegularClass.isNewPlaceForBodyGeneration: Boolean? by FirDeclarationDataRegistry.data(IsNewPlaceForBodyGeneration) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt index bfab7e8470e..cceed391972 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt @@ -46,6 +46,11 @@ object ConeDestructuringDeclarationsOnTopLevel : ConeDiagnostic { get() = "Destructuring declarations are only allowed for local variables/values" } +object ConeDanglingModifierOnTopLevel : ConeDiagnostic { + override val reason: String + get() = "Top level declaration expected" +} + enum class DiagnosticKind { Syntax, ExpressionExpected, diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt index 59bdd19d0b1..19183e95804 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt @@ -387,6 +387,11 @@ class FirRenderer( bodyRenderer?.renderBody(anonymousInitializer.body) } + override fun visitDanglingModifierList(danglingModifierList: FirDanglingModifierList) { + annotationRenderer?.render(danglingModifierList) + print("") + } + override fun visitBlock(block: FirBlock) { bodyRenderer?.renderBody(block) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirDanglingModifierSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirDanglingModifierSymbol.kt new file mode 100644 index 00000000000..cde9bc55423 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirDanglingModifierSymbol.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2010-2020 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. + */ + +package org.jetbrains.kotlin.fir.symbols.impl + +import org.jetbrains.kotlin.fir.declarations.FirDanglingModifierList +import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol + +class FirDanglingModifierSymbol : FirBasedSymbol() { + override fun toString(): String = "${this::class.simpleName}" +} diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt index 4ec6f73db5c..9bf095af447 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt @@ -118,6 +118,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() { val errorExpression by element(Expression, expression, diagnosticHolder) val errorFunction by element(Declaration, function, diagnosticHolder) val errorProperty by element(Declaration, variable, diagnosticHolder) + val danglingModifierList by element(Declaration, declaration, diagnosticHolder) val qualifiedAccessExpression by element(Expression, expression, qualifiedAccess) val qualifiedErrorAccessExpression by element(Expression, expression, diagnosticHolder) val propertyAccessExpression by element(Expression, qualifiedAccessExpression) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index 4ad27f4f463..5f2ca281f8e 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -43,6 +43,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() } impl(anonymousObject) + impl(danglingModifierList) noImpl(anonymousObjectExpression) impl(typeAlias) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index 7dfaea6674b..2db36bb1610 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -456,6 +456,10 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild +field("dispatchReceiverType", coneSimpleKotlinTypeType, nullable = true) } + danglingModifierList.configure { + +symbol("FirDanglingModifierSymbol") + } + file.configure { +field("annotationsContainer", fileAnnotationsContainer).withTransform() +field("packageDirective", packageDirective) diff --git a/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt b/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt index 4334b64dbd3..dff05ff6a63 100644 --- a/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt +++ b/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt @@ -57,6 +57,9 @@ sealed class KtFakeSourceElementKind : KtSourceElementKind() { // with a fake sources which refers to the target expression object GeneratedLambdaLabel : KtFakeSourceElementKind() + // for error element which is created for dangling modifier lists + object DanglingModifierList : KtFakeSourceElementKind() + // for lambdas & functions with expression bodies the return statement is added // with a fake sources which refers to the return target sealed class ImplicitReturn : KtFakeSourceElementKind() { diff --git a/compiler/testData/diagnostics/tests/annotations/DanglingMixed.fir.kt b/compiler/testData/diagnostics/tests/annotations/DanglingMixed.fir.kt deleted file mode 100644 index 28b63a6c62f..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/DanglingMixed.fir.kt +++ /dev/null @@ -1,22 +0,0 @@ -annotation class Ann -annotation class Ann2 - -class C { - fun foo() { - class Local { - @Ann0 - @Ann @Ann3 - @Ann2(1) - @Ann4 - } - } - @Ann0 - @Ann @Ann3 - @Ann2(1) - @Ann4 -} - -@Ann0 -@Ann @Ann3 -@Ann2(1) -@Ann4 diff --git a/compiler/testData/diagnostics/tests/annotations/DanglingMixed.kt b/compiler/testData/diagnostics/tests/annotations/DanglingMixed.kt index 21fd5a02481..5774d1c4992 100644 --- a/compiler/testData/diagnostics/tests/annotations/DanglingMixed.kt +++ b/compiler/testData/diagnostics/tests/annotations/DanglingMixed.kt @@ -1,6 +1,7 @@ +// FIR_IDENTICAL annotation class Ann annotation class Ann2 - +interface I {} class C { fun foo() { class Local { @@ -9,6 +10,12 @@ class C { @Ann2(1) @Ann4 } + val i = object : I { + @Ann0 + @Ann @Ann3 + @Ann2(1) + @Ann4 + } } @Ann0 @Ann @Ann3 diff --git a/compiler/testData/diagnostics/tests/annotations/DanglingMixed.txt b/compiler/testData/diagnostics/tests/annotations/DanglingMixed.txt index dc8aaf388b7..f0eb3d3e768 100644 --- a/compiler/testData/diagnostics/tests/annotations/DanglingMixed.txt +++ b/compiler/testData/diagnostics/tests/annotations/DanglingMixed.txt @@ -21,3 +21,10 @@ public final class C { public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } + +public interface I { + 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/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/fir/FirVisualizerForRawFirDataGenerated.java b/compiler/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/fir/FirVisualizerForRawFirDataGenerated.java index 60e29ece537..faa15ec23ff 100644 --- a/compiler/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/fir/FirVisualizerForRawFirDataGenerated.java +++ b/compiler/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/fir/FirVisualizerForRawFirDataGenerated.java @@ -75,6 +75,18 @@ public class FirVisualizerForRawFirDataGenerated extends AbstractFirVisualizerTe runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt"); } + @Test + @TestMetadata("danglingAnnotationsClassLevel.kt") + public void testDanglingAnnotationsClassLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt"); + } + + @Test + @TestMetadata("danglingAnnotationsFileLevel.kt") + public void testDanglingAnnotationsFileLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt"); + } + @Test @TestMetadata("delegates.kt") public void testDelegates() throws Exception { diff --git a/compiler/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/psi/PsiVisualizerForRawFirDataGenerated.java b/compiler/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/psi/PsiVisualizerForRawFirDataGenerated.java index cb1ed44fd66..db1fd506998 100644 --- a/compiler/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/psi/PsiVisualizerForRawFirDataGenerated.java +++ b/compiler/visualizer/tests-gen/org/jetbrains/kotlin/visualizer/psi/PsiVisualizerForRawFirDataGenerated.java @@ -75,6 +75,18 @@ public class PsiVisualizerForRawFirDataGenerated extends AbstractPsiVisualizerTe runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contextReceivers.kt"); } + @Test + @TestMetadata("danglingAnnotationsClassLevel.kt") + public void testDanglingAnnotationsClassLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsClassLevel.kt"); + } + + @Test + @TestMetadata("danglingAnnotationsFileLevel.kt") + public void testDanglingAnnotationsFileLevel() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/danglingAnnotationsFileLevel.kt"); + } + @Test @TestMetadata("delegates.kt") public void testDelegates() throws Exception {