From d3c91ee9bee1512ed0d542c2e07875d5b461d949 Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Wed, 22 Sep 2021 13:30:01 -0700 Subject: [PATCH] FIR IDE: align resolution behavior of `super` with FE1.0 That is, for a labeled `super`, the keyword should resolve to the super type and the label should be resolved to the current type. --- .../api/fir/references/FirReferenceResolveHelper.kt | 6 ++++++ .../api/fir/FirReferenceResolveTestGenerated.java | 12 ++++++++++++ .../referenceResolve/superWithLabel_caretAtLabel.kt | 8 ++++++++ .../referenceResolve/superWithLabel_caretAtLabel.txt | 2 ++ .../referenceResolve/superWithLabel_caretAtSuper.kt | 8 ++++++++ .../referenceResolve/superWithLabel_caretAtSuper.txt | 2 ++ 6 files changed, 38 insertions(+) create mode 100644 analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtLabel.kt create mode 100644 analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtLabel.txt create mode 100644 analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtSuper.kt create mode 100644 analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtSuper.txt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt index 63952ee9593..0ca444555b2 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/FirReferenceResolveHelper.kt @@ -289,6 +289,12 @@ internal object FirReferenceResolveHelper { session: FirSession, symbolBuilder: KtSymbolByFirBuilder ): Collection { + // If the cursor position is on the label of `super`, we want to resolve to the current class. FIR represents `super` as + // accessing the `super` property on `this`, hence this weird looking if condition. In addition, the current class type is available + // from the dispatch receiver `this`. + if (expression is KtLabelReferenceExpression && fir is FirPropertyAccessExpression && fir.calleeReference is FirSuperReference) { + return listOfNotNull((fir.dispatchReceiver.typeRef as? FirResolvedTypeRef)?.toTargetSymbol(session, symbolBuilder)) + } val calleeReference = if (fir is FirFunctionCall && fir.isImplicitFunctionCall() && diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirReferenceResolveTestGenerated.java b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirReferenceResolveTestGenerated.java index f84d000965d..13a468e9d94 100644 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirReferenceResolveTestGenerated.java +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/FirReferenceResolveTestGenerated.java @@ -474,6 +474,18 @@ public class FirReferenceResolveTestGenerated extends AbstractFirReferenceResolv runTest("analysis/analysis-api/testData/referenceResolve/SeveralOverrides.kt"); } + @Test + @TestMetadata("superWithLabel_caretAtLabel.kt") + public void testSuperWithLabel_caretAtLabel() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtLabel.kt"); + } + + @Test + @TestMetadata("superWithLabel_caretAtSuper.kt") + public void testSuperWithLabel_caretAtSuper() throws Exception { + runTest("analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtSuper.kt"); + } + @Test @TestMetadata("SyntheticProperty.kt") public void testSyntheticProperty() throws Exception { diff --git a/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtLabel.kt b/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtLabel.kt new file mode 100644 index 00000000000..508fc8902c1 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtLabel.kt @@ -0,0 +1,8 @@ +interface A { + fun a() {} +} +class Foo : A { + fun foo() { + super@Foo.a() + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtLabel.txt b/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtLabel.txt new file mode 100644 index 00000000000..90e7781d772 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtLabel.txt @@ -0,0 +1,2 @@ +Resolved to: +0: (in ROOT) class Foo : A diff --git a/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtSuper.kt b/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtSuper.kt new file mode 100644 index 00000000000..f190869fe84 --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtSuper.kt @@ -0,0 +1,8 @@ +interface A { + fun a() {} +} +class Foo : A { + fun foo() { + super@Foo.a() + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtSuper.txt b/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtSuper.txt new file mode 100644 index 00000000000..95089b851fa --- /dev/null +++ b/analysis/analysis-api/testData/referenceResolve/superWithLabel_caretAtSuper.txt @@ -0,0 +1,2 @@ +Resolved to: +0: (in ROOT) interface A