From c30ce4aabe23e36f93c68af704479e56d2377192 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Wed, 23 Aug 2023 13:29:16 +0200 Subject: [PATCH] [FIR] Print operator keyword and token to unresolved diagnostic message #KT-55672 Fixed --- .../diagnostics/KtFirDataClassConverters.kt | 1 + .../api/fir/diagnostics/KtFirDiagnostics.kt | 1 + .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 1 + ...ndexExpressionWithInc.out_of_src_roots.txt | 2 +- .../arrayIndexExpressionWithInc.txt | 2 +- .../arrayIndexExpressionWithIncScript.txt | 4 +- ...qualifiedPartOfQualifiedCallUnresolved.txt | 2 +- ...iedPartOfQualifiedCallUnresolvedScript.txt | 4 +- ...CompilerTestFE10TestdataTestGenerated.java | 6 +++ ...sticCompilerFE10TestDataTestGenerated.java | 6 +++ .../expresssions/operators/plusAssign.fir.txt | 2 +- .../backingFieldVisibility.fir.txt | 18 ++++---- .../backingFieldVisibility.reversed.fir.txt | 24 +++++------ ...ropertiesWithExplicitBackingFields.fir.txt | 2 +- .../propertyTypeNarrowing.fir.txt | 2 +- .../propertyTypeNarrowing.reversed.fir.txt | 6 +-- ...eeOldFrontendDiagnosticsTestGenerated.java | 6 +++ ...siOldFrontendDiagnosticsTestGenerated.java | 6 +++ .../diagnostics/FirDiagnosticsList.kt | 1 + .../fir/analysis/diagnostics/FirErrors.kt | 2 +- .../diagnostics/FirDiagnosticRenderers.kt | 4 ++ .../diagnostics/FirErrorsDefaultMessages.kt | 3 +- .../coneDiagnosticToFirDiagnostic.kt | 12 +++--- .../jetbrains/kotlin/fir/FirCallResolver.kt | 9 +++- .../resolve/diagnostics/ConeDiagnostics.kt | 13 +++++- .../unresolvedOperator.diag.txt | 37 ++++++++++++++++ .../unresolvedOperator.fir.diag.txt | 23 ++++++++++ .../unresolvedOperator.fir.kt | 18 ++++++++ .../unresolvedOperator.kt | 18 ++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 +++ .../kotlin/psi/OperatorNamesToSymbolsTest.kt | 42 +++++++++++++++++++ .../kotlin/util/OperatorNameConventions.kt | 15 +++++++ .../receivers/receiverInjection.fir.txt | 8 ++-- 33 files changed, 257 insertions(+), 49 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.diag.txt create mode 100644 compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.fir.diag.txt create mode 100644 compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.fir.kt create mode 100644 compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.kt create mode 100644 compiler/tests/org/jetbrains/kotlin/psi/OperatorNamesToSymbolsTest.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index 8afd37a2dd7..6b2a81dbc18 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -296,6 +296,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert add(FirErrors.UNRESOLVED_REFERENCE) { firDiagnostic -> UnresolvedReferenceImpl( firDiagnostic.a, + firDiagnostic.b, firDiagnostic as KtPsiDiagnostic, token, ) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index a269b0a0cee..150f4d42941 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -251,6 +251,7 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { interface UnresolvedReference : KtFirDiagnostic { override val diagnosticClass get() = UnresolvedReference::class val reference: String + val operator: String? } interface UnresolvedLabel : KtFirDiagnostic { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index d869c7fd5cf..efe071dda04 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -285,6 +285,7 @@ internal class InvisibleReferenceImpl( internal class UnresolvedReferenceImpl( override val reference: String, + override val operator: String?, firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.UnresolvedReference diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithInc.out_of_src_roots.txt b/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithInc.out_of_src_roots.txt index 5188b33f6a4..23fae07d5c9 100644 --- a/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithInc.out_of_src_roots.txt +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithInc.out_of_src_roots.txt @@ -13,6 +13,6 @@ FILE: [ResolvedTo(IMPORTS)] arrayIndexExpressionWithInc.kt [ResolvedTo(BODY_RESOLVE)] lval : = R|/a| [ResolvedTo(BODY_RESOLVE)] lval : R|kotlin/Int| = Int(0) [ResolvedTo(BODY_RESOLVE)] lval : = R|/|.#(R|/|) - R|/|.#(R|/|, R|/|.#()) + R|/|.#(R|/|, R|/|.#()) R|/| } diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithInc.txt b/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithInc.txt index ac166ff2a10..99d73a18c4c 100644 --- a/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithInc.txt +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithInc.txt @@ -13,6 +13,6 @@ FILE: [ResolvedTo(IMPORTS)] arrayIndexExpressionWithInc.kt [ResolvedTo(BODY_RESOLVE)] lval : R|java/util/ArrayList| = R|/a| [ResolvedTo(BODY_RESOLVE)] lval : R|kotlin/Int| = Int(0) [ResolvedTo(BODY_RESOLVE)] lval : R|kotlin/String| = R|/|.R|SubstitutionOverride|(R|/|) - R|/|.R|SubstitutionOverride|(R|/|, R|/|.#()) + R|/|.R|SubstitutionOverride|(R|/|, R|/|.#()) R|/| } diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithIncScript.txt b/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithIncScript.txt index 535c7e896f9..e7278a78fb1 100644 --- a/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithIncScript.txt +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/expressions/arrayIndexExpressionWithIncScript.txt @@ -17,6 +17,6 @@ FILE: [ResolvedTo(IMPORTS)] arrayIndexExpressionWithIncScript.kts [ResolvedTo(BODY_RESOLVE)] lval : R|java/util/ArrayList| = R|/a| [ResolvedTo(BODY_RESOLVE)] lval : R|kotlin/Int| = Int(0) [ResolvedTo(BODY_RESOLVE)] lval : R|kotlin/String| = R|/|.R|SubstitutionOverride|(R|/|) - R|/|.R|SubstitutionOverride|(R|/|, R|/|.#()) + R|/|.R|SubstitutionOverride|(R|/|, R|/|.#()) R|/| - } \ No newline at end of file + } diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/qualifiedExpressions/qualifiedPartOfQualifiedCallUnresolved.txt b/analysis/low-level-api-fir/testdata/getOrBuildFir/qualifiedExpressions/qualifiedPartOfQualifiedCallUnresolved.txt index cbad6bd8455..9cc84ece4ab 100644 --- a/analysis/low-level-api-fir/testdata/getOrBuildFir/qualifiedExpressions/qualifiedPartOfQualifiedCallUnresolved.txt +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/qualifiedExpressions/qualifiedPartOfQualifiedCallUnresolved.txt @@ -16,7 +16,7 @@ FILE: [ResolvedTo(IMPORTS)] qualifiedPartOfQualifiedCallUnresolved.kt { [ResolvedTo(BODY_RESOLVE)] lval : R|ERROR CLASS: Unresolved name: peek| = #() [ResolvedTo(BODY_RESOLVE)] lval : = R|/|.# - R|/|.# = R|/|.#() + R|/|.# = R|/|.#() R|/| } diff --git a/analysis/low-level-api-fir/testdata/getOrBuildFir/qualifiedExpressions/qualifiedPartOfQualifiedCallUnresolvedScript.txt b/analysis/low-level-api-fir/testdata/getOrBuildFir/qualifiedExpressions/qualifiedPartOfQualifiedCallUnresolvedScript.txt index c4fb0c338a5..1ef4bbbb65c 100644 --- a/analysis/low-level-api-fir/testdata/getOrBuildFir/qualifiedExpressions/qualifiedPartOfQualifiedCallUnresolvedScript.txt +++ b/analysis/low-level-api-fir/testdata/getOrBuildFir/qualifiedExpressions/qualifiedPartOfQualifiedCallUnresolvedScript.txt @@ -20,10 +20,10 @@ FILE: [ResolvedTo(IMPORTS)] qualifiedPartOfQualifiedCallUnresolvedScript.kts { [ResolvedTo(BODY_RESOLVE)] lval : R|ERROR CLASS: Unresolved name: peek| = #() [ResolvedTo(BODY_RESOLVE)] lval : = R|/|.# - R|/|.# = R|/|.#() + R|/|.# = R|/|.#() R|/| } } - } \ No newline at end of file + } 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 b8cd46448fe..d56cc9a334e 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 @@ -23958,6 +23958,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/operatorsOverloading/plusAssignOnVarAndCollections.kt"); } + @Test + @TestMetadata("unresolvedOperator.kt") + public void testUnresolvedOperator() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/operatorsOverloading/until") @TestDataPath("$PROJECT_ROOT") 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 e5bf8d9297e..96f31065d9a 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 @@ -23958,6 +23958,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/operatorsOverloading/plusAssignOnVarAndCollections.kt"); } + @Test + @TestMetadata("unresolvedOperator.kt") + public void testUnresolvedOperator() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/operatorsOverloading/until") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/operators/plusAssign.fir.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/operators/plusAssign.fir.txt index 0361b6bceb4..b8f1dd66625 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/operators/plusAssign.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/operators/plusAssign.fir.txt @@ -15,7 +15,7 @@ FILE: plusAssign.kt } public final fun test_1(): R|kotlin/Unit| { lval f: R|Foo| = R|/Foo.Foo|() - R|/f|.#(R|/f|) + R|/f|.#(R|/f|) } public final fun test_2(): R|kotlin/Unit| { lval f: R|Foo| = R|/Foo.Foo|() diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/backingFieldVisibility.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/backingFieldVisibility.fir.txt index 2942fb461c5..9cbb8ebd020 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/backingFieldVisibility.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/backingFieldVisibility.fir.txt @@ -24,22 +24,22 @@ FILE: A.kt public final fun rest(): R|kotlin/Unit| { lval aI: R|kotlin/Int| = R|/A.A|().R|/A.a|.R|kotlin/Int.plus|(Int(10)) lval bI: R|kotlin/Int| = R|/A.A|().R|/A.b|.R|kotlin/Int.plus|(Int(20)) - lval cI: = R|/A.A|().R|/A.c|.#(Int(30)) - lval dI: = R|/A.A|().R|/A.d|.#(Int(40)) + lval cI: = R|/A.A|().R|/A.c|.#(Int(30)) + lval dI: = R|/A.A|().R|/A.d|.#(Int(40)) } } public final fun test(): R|kotlin/Unit| { - lval aA: = R|/A.A|().R|/A.a|.#(Int(10)) + lval aA: = R|/A.A|().R|/A.a|.#(Int(10)) lval bA: R|kotlin/Int| = R|/A.A|().R|/A.b|.R|kotlin/Int.plus|(Int(20)) - lval cA: = R|/A.A|().R|/A.c|.#(Int(30)) - lval dA: = R|/A.A|().R|/A.d|.#(Int(40)) + lval cA: = R|/A.A|().R|/A.c|.#(Int(30)) + lval dA: = R|/A.A|().R|/A.d|.#(Int(40)) } Module: main FILE: B.kt public final fun main(): R|kotlin/Unit| { - lval aB: = R|/A.A|().R|/A.a|.#(Int(10)) - lval bB: = R|/A.A|().R|/A.b|.#(Int(20)) - lval cB: = R|/A.A|().R|/A.c|.#(Int(30)) - lval dB: = R|/A.A|().R|/A.d|.#(Int(40)) + lval aB: = R|/A.A|().R|/A.a|.#(Int(10)) + lval bB: = R|/A.A|().R|/A.b|.#(Int(20)) + lval cB: = R|/A.A|().R|/A.c|.#(Int(30)) + lval dB: = R|/A.A|().R|/A.d|.#(Int(40)) } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/backingFieldVisibility.reversed.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/backingFieldVisibility.reversed.fir.txt index a404fba8684..67b9f041500 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/backingFieldVisibility.reversed.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/backingFieldVisibility.reversed.fir.txt @@ -22,24 +22,24 @@ FILE: A.kt public get(): R|kotlin/Number| public final fun rest(): R|kotlin/Unit| { - lval aI: = R|/A.A|().R|/A.a|.#(Int(10)) - lval bI: = R|/A.A|().R|/A.b|.#(Int(20)) - lval cI: = R|/A.A|().R|/A.c|.#(Int(30)) - lval dI: = R|/A.A|().R|/A.d|.#(Int(40)) + lval aI: = R|/A.A|().R|/A.a|.#(Int(10)) + lval bI: = R|/A.A|().R|/A.b|.#(Int(20)) + lval cI: = R|/A.A|().R|/A.c|.#(Int(30)) + lval dI: = R|/A.A|().R|/A.d|.#(Int(40)) } } public final fun test(): R|kotlin/Unit| { - lval aA: = R|/A.A|().R|/A.a|.#(Int(10)) - lval bA: = R|/A.A|().R|/A.b|.#(Int(20)) - lval cA: = R|/A.A|().R|/A.c|.#(Int(30)) - lval dA: = R|/A.A|().R|/A.d|.#(Int(40)) + lval aA: = R|/A.A|().R|/A.a|.#(Int(10)) + lval bA: = R|/A.A|().R|/A.b|.#(Int(20)) + lval cA: = R|/A.A|().R|/A.c|.#(Int(30)) + lval dA: = R|/A.A|().R|/A.d|.#(Int(40)) } Module: main FILE: B.kt public final fun main(): R|kotlin/Unit| { - lval aB: = R|/A.A|().R|/A.a|.#(Int(10)) - lval bB: = R|/A.A|().R|/A.b|.#(Int(20)) - lval cB: = R|/A.A|().R|/A.c|.#(Int(30)) - lval dB: = R|/A.A|().R|/A.d|.#(Int(40)) + lval aB: = R|/A.A|().R|/A.a|.#(Int(10)) + lval bB: = R|/A.A|().R|/A.b|.#(Int(20)) + lval cB: = R|/A.A|().R|/A.c|.#(Int(30)) + lval dB: = R|/A.A|().R|/A.d|.#(Int(40)) } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/overriddenPropertiesWithExplicitBackingFields.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/overriddenPropertiesWithExplicitBackingFields.fir.txt index 40adf460767..ad8f5b53593 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/overriddenPropertiesWithExplicitBackingFields.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/overriddenPropertiesWithExplicitBackingFields.fir.txt @@ -12,7 +12,7 @@ FILE: overriddenPropertiesWithExplicitBackingFields.kt } public final fun test(): R|kotlin/Unit| { - #(this@R|/A|.R|/A.it|.#(Int(1))) + #(this@R|/A|.R|/A.it|.#(Int(1))) } } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/propertyTypeNarrowing.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/propertyTypeNarrowing.fir.txt index e7d9ed0cae0..ca55f3dbe6f 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/propertyTypeNarrowing.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/propertyTypeNarrowing.fir.txt @@ -19,7 +19,7 @@ FILE: propertyTypeNarrowing.kt } public final fun test(): R|kotlin/Unit| { - lval c: = R|/A.A|().R|/A.it|.#(Int(1)) + lval c: = R|/A.A|().R|/A.it|.#(Int(1)) lval d: R|kotlin/Unit| = R|/test|() lval b: R|kotlin/Int| = R|/A.A|().R|/A.p|.R|kotlin/Int.plus|(Int(2)) } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/propertyTypeNarrowing.reversed.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/propertyTypeNarrowing.reversed.fir.txt index 61612aad46c..09ee228feee 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/propertyTypeNarrowing.reversed.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/properties/backingField/propertyTypeNarrowing.reversed.fir.txt @@ -8,8 +8,8 @@ FILE: propertyTypeNarrowing.reversed.kt private : R|kotlin/Int| = Int(4) public get(): R|kotlin/Number| - public final fun test(): { - ^test this@R|/A|.R|/A.it|.#(Int(3)) + public final fun test(): { + ^test this@R|/A|.R|/A.it|.#(Int(3)) } public final val p: R|kotlin/Int| = Int(5) @@ -19,7 +19,7 @@ FILE: propertyTypeNarrowing.reversed.kt } public final fun test(): R|kotlin/Unit| { - lval c: = R|/A.A|().R|/A.it|.#(Int(1)) + lval c: = R|/A.A|().R|/A.it|.#(Int(1)) lval d: R|kotlin/Unit| = R|/test|() lval b: R|kotlin/Int| = R|/A.A|().R|/A.p|.R|kotlin/Int.plus|(Int(2)) } 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 28552d76f95..5847a3a9e7d 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 @@ -23958,6 +23958,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/operatorsOverloading/plusAssignOnVarAndCollections.kt"); } + @Test + @TestMetadata("unresolvedOperator.kt") + public void testUnresolvedOperator() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/operatorsOverloading/until") @TestDataPath("$PROJECT_ROOT") 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 6dc692fdea3..b7a8725f53c 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 @@ -23964,6 +23964,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/operatorsOverloading/plusAssignOnVarAndCollections.kt"); } + @Test + @TestMetadata("unresolvedOperator.kt") + public void testUnresolvedOperator() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/operatorsOverloading/until") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index b0f00ad85a9..019ca2bb104 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -118,6 +118,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { } val UNRESOLVED_REFERENCE by error(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) { parameter("reference") + parameter("operator") } val UNRESOLVED_LABEL by error(PositioningStrategy.LABEL) val DESERIALIZATION_ERROR by error() diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 3a03db23455..1d22faaad9c 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -158,7 +158,7 @@ object FirErrors { // Unresolved val INVISIBLE_REFERENCE by error3, Visibility, ClassId?>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) - val UNRESOLVED_REFERENCE by error1(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) + val UNRESOLVED_REFERENCE by error2(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED) val UNRESOLVED_LABEL by error0(SourceElementPositioningStrategies.LABEL) val DESERIALIZATION_ERROR by error0() val ERROR_FROM_JAVA_RESOLUTION by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt index c68380ecc16..331cc8cfeeb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt @@ -189,4 +189,8 @@ object FirDiagnosticRenderers { val OPTIONAL_SENTENCE = Renderer { it: String? -> if (!it.isNullOrBlank()) " $it." else "" } + + val FOR_OPTIONAL_OPERATOR = Renderer { it: String? -> + if (!it.isNullOrBlank()) " for operator '$it'" else "" + } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index 700d6510be0..2a505999b51 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.diagnostics.rendering.LanguageFeatureMessageRenderer import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.AMBIGUOUS_CALLS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.CALLEE_NAME import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FOR_OPTIONAL_OPERATOR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_NAMES_IN_TYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FUNCTIONAL_TYPE_KINDS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.MODULE_DATA @@ -771,7 +772,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { TO_STRING ) map.put(MISSING_CONSTRUCTOR_KEYWORD, "Use the 'constructor' keyword after the modifiers of the primary constructor.") - map.put(UNRESOLVED_REFERENCE, "Unresolved reference ''{0}''.", NULLABLE_STRING) + map.put(UNRESOLVED_REFERENCE, "Unresolved reference ''{0}''{1}.", NULLABLE_STRING, FOR_OPTIONAL_OPERATOR) map.put(UNRESOLVED_IMPORT, "Unresolved reference ''{0}''.", NULLABLE_STRING) // & map.put(DUPLICATE_PARAMETER_NAME_IN_FUNCTION_TYPE, "Duplicate parameter name in a function type.") map.put(UNRESOLVED_LABEL, "Unresolved label.") diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index 10a18848893..768948da30b 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -50,12 +50,13 @@ private fun ConeDiagnostic.toKtDiagnostic( ): KtDiagnostic? = when (this) { is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.createOn( source, - this.name.asString() + this.name.asString(), + null, ) - is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.classId.asString()) - is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.name.asString()) - is ConeUnresolvedTypeQualifierError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.qualifier) + is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.classId.asString(), null) + is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, name.asString(), operatorToken) + is ConeUnresolvedTypeQualifierError -> FirErrors.UNRESOLVED_REFERENCE.createOn(source, this.qualifier, null) is ConeFunctionCallExpectedError -> FirErrors.FUNCTION_CALL_EXPECTED.createOn(source, this.name.asString(), this.hasValueParameters) is ConeFunctionExpectedError -> FirErrors.FUNCTION_EXPECTED.createOn(source, this.expression, this.type) is ConeNoConstructorError -> FirErrors.NO_CONSTRUCTOR.createOn(callOrAssignmentSource ?: source) @@ -73,7 +74,8 @@ private fun ConeDiagnostic.toKtDiagnostic( // See: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-deprecated/ FirErrors.UNRESOLVED_REFERENCE.createOn( source, - ((this.candidateSymbol as? FirCallableSymbol)?.name ?: SpecialNames.NO_NAME_PROVIDED).asString() + ((this.candidateSymbol as? FirCallableSymbol)?.name ?: SpecialNames.NO_NAME_PROVIDED).asString(), + null, ) } 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 23c16ff0ee6..e16c1e6754a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -53,6 +53,8 @@ import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.isSuccess import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.util.CodeFragmentAdjustment +import org.jetbrains.kotlin.util.OperatorNameConventions +import org.jetbrains.kotlin.utils.addToStdlib.runIf class FirCallResolver( private val components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents, @@ -700,6 +702,9 @@ class FirCallResolver( expectedCandidates: Collection? = null ): FirNamedReference { val source = reference.source + val operatorToken = runIf(callInfo.origin == FirFunctionCallOrigin.Operator) { + OperatorNameConventions.TOKENS_BY_OPERATOR_NAME[name] + } val diagnostic = when { expectedCallKind != null -> { @@ -738,7 +743,7 @@ class FirCallResolver( singleExpectedCandidate ) } - else -> ConeUnresolvedNameError(name) + else -> ConeUnresolvedNameError(name, operatorToken) } } } @@ -754,7 +759,7 @@ class FirCallResolver( explicitReceiver.resolvedType, ) reference is FirSuperReference && (reference.superTypeRef.firClassLike(session) as? FirClass)?.isInterface == true -> ConeNoConstructorError - else -> ConeUnresolvedNameError(name) + else -> ConeUnresolvedNameError(name, operatorToken) } } diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt index 6051fe4959e..d691fb473d9 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/diagnostics/ConeDiagnostics.kt @@ -65,9 +65,18 @@ class ConeUnresolvedTypeQualifierError(val qualifiers: List, o override val reason: String get() = "Symbol not found for $qualifier${if (isNullable) "?" else ""}" } -class ConeUnresolvedNameError(val name: Name) : ConeUnresolvedError { +class ConeUnresolvedNameError( + val name: Name, + val operatorToken: String? = null, +) : ConeUnresolvedError { override val qualifier: String get() = name.asString() - override val reason: String get() = "Unresolved name: $name" + override val reason: String get() = "Unresolved name: $prettyReference" + + private val prettyReference: String + get() = when (val token = operatorToken) { + null -> name.toString() + else -> "$name ($token)" + } } class ConeFunctionCallExpectedError( diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.diag.txt b/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.diag.txt new file mode 100644 index 00000000000..849598461fd --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.diag.txt @@ -0,0 +1,37 @@ +/unresolvedOperator.kt:6:6: error: unresolved reference: ++ + a++ + ^ +/unresolvedOperator.kt:7:6: error: unresolved reference: -- + a-- + ^ +/unresolvedOperator.kt:8:5: error: unresolved reference: + + +a + ^ +/unresolvedOperator.kt:9:5: error: unresolved reference: - + -a + ^ +/unresolvedOperator.kt:10:5: error: unresolved reference: ! + !a + ^ +/unresolvedOperator.kt:11:7: error: unresolved reference: * + a * a + ^ +/unresolvedOperator.kt:12:10: error: unresolved reference. None of the following candidates is applicable because of receiver type mismatch: +public operator fun String?.plus(other: Any?): String defined in kotlin + true + false + ^ +/unresolvedOperator.kt:13:7: error: unresolved reference: - + a - a + ^ +/unresolvedOperator.kt:14:7: error: unresolved reference: / + a / a + ^ +/unresolvedOperator.kt:15:7: error: unresolved reference: % + a % a + ^ +/unresolvedOperator.kt:16:7: error: unresolved reference: .. + a .. a + ^ +/unresolvedOperator.kt:17:7: error: unresolved reference: ..< + a ..< a + ^ diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.fir.diag.txt b/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.fir.diag.txt new file mode 100644 index 00000000000..0cc9da8e68b --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.fir.diag.txt @@ -0,0 +1,23 @@ +/unresolvedOperator.fir.kt:(67,69): error: Unresolved reference 'inc' for operator '++'. + +/unresolvedOperator.fir.kt:(75,77): error: Unresolved reference 'dec' for operator '--'. + +/unresolvedOperator.fir.kt:(82,83): error: Unresolved reference 'unaryPlus' for operator '+'. + +/unresolvedOperator.fir.kt:(89,90): error: Unresolved reference 'unaryMinus' for operator '-'. + +/unresolvedOperator.fir.kt:(96,97): error: Unresolved reference 'not' for operator '!'. + +/unresolvedOperator.fir.kt:(105,106): error: Unresolved reference 'times' for operator '*'. + +/unresolvedOperator.fir.kt:(118,119): error: Unresolved reference 'plus' for operator '+'. + +/unresolvedOperator.fir.kt:(132,133): error: Unresolved reference 'minus' for operator '-'. + +/unresolvedOperator.fir.kt:(142,143): error: Unresolved reference 'div' for operator '/'. + +/unresolvedOperator.fir.kt:(152,153): error: Unresolved reference 'rem' for operator '%'. + +/unresolvedOperator.fir.kt:(162,164): error: Unresolved reference 'rangeTo' for operator '..'. + +/unresolvedOperator.fir.kt:(173,176): error: Unresolved reference 'rangeUntil' for operator '..<'. diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.fir.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.fir.kt new file mode 100644 index 00000000000..d41240a882e --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.fir.kt @@ -0,0 +1,18 @@ +// RENDER_DIAGNOSTICS_FULL_TEXT + +fun test() { + var a = "" + + a++ + a-- + +a + -a + !a + a * a + true + false + a - a + a / a + a % a + a .. a + a ..< a +} diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.kt new file mode 100644 index 00000000000..f7b19f976fc --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.kt @@ -0,0 +1,18 @@ +// RENDER_DIAGNOSTICS_FULL_TEXT + +fun test() { + var a = "" + + a++ + a-- + +a + -a + !a + a * a + true + false + a - a + a / a + a % a + a .. a + a ..< 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 e95b1395e5d..cbb38a65b1f 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 @@ -25578,6 +25578,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/operatorsOverloading/plusAssignOnVarAndCollections.kt"); } + @Test + @TestMetadata("unresolvedOperator.kt") + public void testUnresolvedOperator() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/unresolvedOperator.kt"); + } + @Nested @TestMetadata("compiler/testData/diagnostics/tests/operatorsOverloading/until") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests/org/jetbrains/kotlin/psi/OperatorNamesToSymbolsTest.kt b/compiler/tests/org/jetbrains/kotlin/psi/OperatorNamesToSymbolsTest.kt new file mode 100644 index 00000000000..4025191613c --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/psi/OperatorNamesToSymbolsTest.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2023 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.psi + +import org.jetbrains.kotlin.lexer.KtSingleValueToken +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.expressions.OperatorConventions +import org.jetbrains.kotlin.util.OperatorNameConventions +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +class OperatorNamesToSymbolsTest { + @Test + fun testAllOperatorsMapped() { + val allEntries = OperatorNameConventions.TOKENS_BY_OPERATOR_NAME.toMutableMap() + val mapName = "${OperatorNameConventions::class.java.simpleName}.${OperatorNameConventions::TOKENS_BY_OPERATOR_NAME.name}" + + fun check(token: KtSingleValueToken, name: Name) { + val mappedToken = allEntries.remove(name) + assertNotNull(mappedToken, "'$name' not in $mapName") + assertEquals(token.value, mappedToken, "Token not matching") + } + + for ((token, name) in OperatorConventions.UNARY_OPERATION_NAMES) { + check(token, name) + } + + for ((token, name) in OperatorConventions.BINARY_OPERATION_NAMES) { + check(token, name) + } + + assertTrue( + allEntries.isEmpty(), + "Entries in $mapName that were not in ${OperatorConventions::class.java.simpleName}: ${allEntries.entries.joinToString()}" + ) + } +} diff --git a/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt b/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt index 0b71bec0fae..a3589821af1 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt @@ -98,4 +98,19 @@ object OperatorNameConventions { @JvmField val STATEMENT_LIKE_OPERATORS = setOf(SET) + ASSIGNMENT_OPERATIONS + + val TOKENS_BY_OPERATOR_NAME = mapOf( + INC to "++", + DEC to "--", + UNARY_PLUS to "+", + UNARY_MINUS to "-", + NOT to "!", + TIMES to "*", + PLUS to "+", + MINUS to "-", + DIV to "/", + REM to "%", + RANGE_TO to "..", + RANGE_UNTIL to "..<", + ) } diff --git a/plugins/fir-plugin-prototype/testData/diagnostics/receivers/receiverInjection.fir.txt b/plugins/fir-plugin-prototype/testData/diagnostics/receivers/receiverInjection.fir.txt index 1d95ce139dc..5ba49033dbe 100644 --- a/plugins/fir-plugin-prototype/testData/diagnostics/receivers/receiverInjection.fir.txt +++ b/plugins/fir-plugin-prototype/testData/diagnostics/receivers/receiverInjection.fir.txt @@ -10,8 +10,8 @@ FILE: receiverInjection.kt public final fun injectAlgebra(): R|kotlin/Unit| { } public final fun test_1(a1: R|A|, a2: R|A|, b1: R|B|, b2: R|B|): R|kotlin/Unit| { - R|/a1|.#(R|/a2|) - R|/b1|.#(R|/b2|) + R|/a1|.#(R|/a2|) + R|/b1|.#(R|/b2|) R|/injectAlgebra|() (this@R|/test_1|, R|/a1|).R|SubstitutionOverride|(R|/a2|) (this@R|/test_1|, R|/b1|).R|SubstitutionOverride#|(R|/b2|) @@ -20,7 +20,7 @@ FILE: receiverInjection.kt (this@R|/test_1|, R|/b1|).R|SubstitutionOverride|(R|/b2|) } public final fun test_2(a1: R|A|, a2: R|A|, cond: R|kotlin/Boolean|): R|kotlin/Unit| { - R|/a1|.#(R|/a2|) + R|/a1|.#(R|/a2|) when () { R|/cond| -> { R|/injectAlgebra|() @@ -28,5 +28,5 @@ FILE: receiverInjection.kt } } - R|/a1|.#(R|/a2|) + R|/a1|.#(R|/a2|) }