From 8fb94612764eb9491f52f51b3d7c4d68fa192ef3 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 31 Jul 2023 16:12:17 +0000 Subject: [PATCH] [Fir] get candidate from missed type args diagnostics in annotation call Otherwise, navigation to unresolved reference is impossible ^ KTIJ-26441 In order to avoid duplicated diagnostic, wrapper is still used. Symbol collector is updated to retrieve symbols from that wrapper. Merge-request: KT-MR-11381 Merged-by: Anna Kozlova --- .../kotlin/analysis/api/fir/FirUtils.kt | 2 ++ .../missedTypeArgumentsInAnnotationCall.kt | 7 ++++++ .../missedTypeArgumentsInAnnotationCall.txt | 23 +++++++++++++++++++ ...ContentRootGetOrBuildFirTestGenerated.java | 6 +++++ .../fir/SourceGetOrBuildFirTestGenerated.java | 6 +++++ ...CompilerTestFE10TestdataTestGenerated.java | 6 +++++ ...sticCompilerFE10TestDataTestGenerated.java | 6 +++++ ...eeOldFrontendDiagnosticsTestGenerated.java | 6 +++++ ...siOldFrontendDiagnosticsTestGenerated.java | 6 +++++ .../jetbrains/kotlin/fir/FirCallResolver.kt | 5 +++- .../missedTypeArgumentsInAnnotationCall.kt | 7 ++++++ .../test/runners/DiagnosticTestGenerated.java | 6 +++++ 12 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/missedTypeArgumentsInAnnotationCall.kt create mode 100644 analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/missedTypeArgumentsInAnnotationCall.txt create mode 100644 compiler/testData/diagnostics/tests/missedTypeArgumentsInAnnotationCall.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt index 747e2d33835..560696f0133 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirUtils.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall @@ -68,6 +69,7 @@ internal fun ConeDiagnostic.getCandidateSymbols(): Collection> } is ConeDiagnosticWithCandidates -> candidateSymbols is ConeDiagnosticWithSymbol<*> -> listOf(symbol) + is ConeStubDiagnostic -> original.getCandidateSymbols() else -> emptyList() } diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/missedTypeArgumentsInAnnotationCall.kt b/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/missedTypeArgumentsInAnnotationCall.kt new file mode 100644 index 00000000000..42a40e92af4 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/missedTypeArgumentsInAnnotationCall.kt @@ -0,0 +1,7 @@ +// LOOK_UP_FOR_ELEMENT_OF_TYPE: org.jetbrains.kotlin.psi.KtNameReferenceExpression +package usage + +annotation class B + +@B +class A \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/missedTypeArgumentsInAnnotationCall.txt b/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/missedTypeArgumentsInAnnotationCall.txt new file mode 100644 index 00000000000..088a1531099 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/missedTypeArgumentsInAnnotationCall.txt @@ -0,0 +1,23 @@ +KT element: KtNameReferenceExpression +FIR element: FirErrorNamedReferenceImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +# + +FIR FILE: +FILE: [ResolvedTo(IMPORTS)] missedTypeArgumentsInAnnotationCall.kt + package usage + + public? final? [ResolvedTo(RAW_FIR)] annotation class B<[ResolvedTo(RAW_FIR)] T> : R|kotlin/Annotation| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=B] constructor<[ResolvedTo(RAW_FIR)] T>(): R|usage/B| { + LAZY_super + } + + } + @[Types]() public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class A : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=A] constructor(): R|usage/A| { + LAZY_super + } + + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/OutOfContentRootGetOrBuildFirTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/OutOfContentRootGetOrBuildFirTestGenerated.java index 872ad8cf752..d5d48530c79 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/OutOfContentRootGetOrBuildFirTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/OutOfContentRootGetOrBuildFirTestGenerated.java @@ -907,6 +907,12 @@ public class OutOfContentRootGetOrBuildFirTestGenerated extends AbstractOutOfCon runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/javaClassLiteral.kt"); } + @Test + @TestMetadata("missedTypeArgumentsInAnnotationCall.kt") + public void testMissedTypeArgumentsInAnnotationCall() throws Exception { + runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/missedTypeArgumentsInAnnotationCall.kt"); + } + @Test @TestMetadata("secondaryConstructor.kt") public void testSecondaryConstructor() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/SourceGetOrBuildFirTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/SourceGetOrBuildFirTestGenerated.java index 2a696eebb73..2f5030460c1 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/SourceGetOrBuildFirTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/SourceGetOrBuildFirTestGenerated.java @@ -907,6 +907,12 @@ public class SourceGetOrBuildFirTestGenerated extends AbstractSourceGetOrBuildFi runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/javaClassLiteral.kt"); } + @Test + @TestMetadata("missedTypeArgumentsInAnnotationCall.kt") + public void testMissedTypeArgumentsInAnnotationCall() throws Exception { + runTest("analysis/low-level-api-fir/testdata/getOrBuildFir/invalidCode/missedTypeArgumentsInAnnotationCall.kt"); + } + @Test @TestMetadata("secondaryConstructor.kt") public void testSecondaryConstructor() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index b033771c261..4e241db93b3 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -687,6 +687,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/localInterfaces.kt"); } + @Test + @TestMetadata("missedTypeArgumentsInAnnotationCall.kt") + public void testMissedTypeArgumentsInAnnotationCall() throws Exception { + runTest("compiler/testData/diagnostics/tests/missedTypeArgumentsInAnnotationCall.kt"); + } + @Test @TestMetadata("missingIteratorMissing.kt") public void testMissingIteratorMissing() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index a68525c70e8..3e959b1dec0 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -687,6 +687,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/localInterfaces.kt"); } + @Test + @TestMetadata("missedTypeArgumentsInAnnotationCall.kt") + public void testMissedTypeArgumentsInAnnotationCall() throws Exception { + runTest("compiler/testData/diagnostics/tests/missedTypeArgumentsInAnnotationCall.kt"); + } + @Test @TestMetadata("missingIteratorMissing.kt") public void testMissingIteratorMissing() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index 63cb274391e..95aae2fcaff 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -687,6 +687,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/localInterfaces.kt"); } + @Test + @TestMetadata("missedTypeArgumentsInAnnotationCall.kt") + public void testMissedTypeArgumentsInAnnotationCall() throws Exception { + runTest("compiler/testData/diagnostics/tests/missedTypeArgumentsInAnnotationCall.kt"); + } + @Test @TestMetadata("missingIteratorMissing.kt") public void testMissingIteratorMissing() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index d47b9cf04ff..aa0f60a628d 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -687,6 +687,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/localInterfaces.kt"); } + @Test + @TestMetadata("missedTypeArgumentsInAnnotationCall.kt") + public void testMissedTypeArgumentsInAnnotationCall() throws Exception { + runTest("compiler/testData/diagnostics/tests/missedTypeArgumentsInAnnotationCall.kt"); + } + @Test @TestMetadata("missingIteratorMissing.kt") public void testMissingIteratorMissing() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index a4de823f3fb..99a0e280e4a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -586,7 +586,10 @@ class FirCallResolver( callInfo, if (annotationClassSymbol != null) ConeIllegalAnnotationError(reference.name) //calleeReference and annotationTypeRef are both error nodes so we need to avoid doubling of the diagnostic report - else ConeStubDiagnostic(ConeUnresolvedNameError(reference.name)), + else ConeStubDiagnostic( + //prefer diagnostic with symbol, e.g. to use the symbol during navigation in IDE + (annotation.typeRef.coneType as? ConeErrorType)?.diagnostic as? ConeDiagnosticWithSymbol<*> + ?: ConeUnresolvedNameError(reference.name)), reference.source ) } diff --git a/compiler/testData/diagnostics/tests/missedTypeArgumentsInAnnotationCall.kt b/compiler/testData/diagnostics/tests/missedTypeArgumentsInAnnotationCall.kt new file mode 100644 index 00000000000..5c1eb7e59dd --- /dev/null +++ b/compiler/testData/diagnostics/tests/missedTypeArgumentsInAnnotationCall.kt @@ -0,0 +1,7 @@ +// FIR_IDENTICAL +package usage + +annotation class B + +@B +class A diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 37d843aa3c7..1114ad8fada 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -687,6 +687,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/localInterfaces.kt"); } + @Test + @TestMetadata("missedTypeArgumentsInAnnotationCall.kt") + public void testMissedTypeArgumentsInAnnotationCall() throws Exception { + runTest("compiler/testData/diagnostics/tests/missedTypeArgumentsInAnnotationCall.kt"); + } + @Test @TestMetadata("missingIteratorMissing.kt") public void testMissingIteratorMissing() throws Exception {