From d6d5e3888e0dfd0bbee4a2efaba3423c285fcb22 Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Mon, 29 Jul 2024 18:03:31 +0200 Subject: [PATCH] KTIJ-25346 [kotlin] Handle typealiased constructors referencing SAM types in K2 Import Optimizer There are currently no good utility in AA to do the "SAM constructor -> SAM type" navigation; see KT-70301. GitOrigin-RevId: a61ee3949f7892cf19276bf7bfcdc5c9f2c8105f --- .../imports/UsedReferencesCollector.kt | 21 +++++++++++++++++++ .../FirJvmOptimizeImportsTestGenerated.java | 10 +++++++++ .../JsOptimizeImportsTestGenerated.java | 10 +++++++++ .../JvmOptimizeImportsTestGenerated.java | 10 +++++++++ .../common/SamConstructor_nestedClass.kt | 13 ++++++++++++ .../SamConstructor_nestedClass.kt.after | 13 ++++++++++++ ...edConstructor_samConstructor.dependency.kt | 7 +++++++ .../TypeAliasedConstructor_samConstructor.kt | 8 +++++++ ...AliasedConstructor_samConstructor.kt.after | 7 +++++++ 9 files changed, 99 insertions(+) create mode 100644 plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/SamConstructor_nestedClass.kt create mode 100644 plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/SamConstructor_nestedClass.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.dependency.kt create mode 100644 plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt create mode 100644 plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt.after diff --git a/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/imports/UsedReferencesCollector.kt b/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/imports/UsedReferencesCollector.kt index 373397478dc7..f4a6f8c2c45a 100644 --- a/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/imports/UsedReferencesCollector.kt +++ b/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/imports/UsedReferencesCollector.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.idea.references.KDocReference import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference import org.jetbrains.kotlin.idea.references.KtReference import org.jetbrains.kotlin.idea.references.mainReference +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.withClassId @@ -131,6 +132,12 @@ internal class UsedReferencesCollector(private val file: KtFile) { targetClass?.let { resolveTypeAliasedConstructorReference(reference, it) } ?: targetClass } + target is KaSamConstructorSymbol -> { + val targetClass = findSamClassFor(target) + + targetClass?.let { resolveTypeAliasedConstructorReference(reference, it) } ?: targetClass + } + else -> target } @@ -166,6 +173,20 @@ internal class UsedReferencesCollector(private val file: KtFile) { } } +/** + * Finds the original SAM type by the [samConstructorSymbol]. + * + * A workaround for the KT-70301. + */ +private fun KaSession.findSamClassFor(samConstructorSymbol: KaSamConstructorSymbol): KaClassSymbol? { + val samCallableId = samConstructorSymbol.callableId ?: return null + if (samCallableId.isLocal) return null + + val samClassId = ClassId.fromString(samCallableId.toString()) + + return findClass(samClassId) +} + /** * Takes a [reference] pointing to a typealiased constructor call like `FooAlias()`, * and [expandedClassSymbol] pointing to the expanded class `Foo`. diff --git a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/FirJvmOptimizeImportsTestGenerated.java b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/FirJvmOptimizeImportsTestGenerated.java index 2ee01278c2b1..a5c1464c1eda 100644 --- a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/FirJvmOptimizeImportsTestGenerated.java +++ b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/FirJvmOptimizeImportsTestGenerated.java @@ -764,6 +764,11 @@ public abstract class FirJvmOptimizeImportsTestGenerated extends AbstractFirJvmO runTest("../../idea/tests/testData/editor/optimizeImports/common/ResolvedImportAndUnresolvedReference.kt"); } + @TestMetadata("SamConstructor_nestedClass.kt") + public void testSamConstructor_nestedClass() throws Exception { + runTest("../../idea/tests/testData/editor/optimizeImports/common/SamConstructor_nestedClass.kt"); + } + @TestMetadata("SeveralClasses.kt") public void testSeveralClasses() throws Exception { runTest("../../idea/tests/testData/editor/optimizeImports/common/SeveralClasses.kt"); @@ -794,6 +799,11 @@ public abstract class FirJvmOptimizeImportsTestGenerated extends AbstractFirJvmO runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_annotation.kt"); } + @TestMetadata("TypeAliasedConstructor_samConstructor.kt") + public void testTypeAliasedConstructor_samConstructor() throws Exception { + runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt"); + } + @TestMetadata("TypeAliasedConstructor_sameName.kt") public void testTypeAliasedConstructor_sameName() throws Exception { runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_sameName.kt"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/imports/JsOptimizeImportsTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/imports/JsOptimizeImportsTestGenerated.java index 392ad88e4e80..fb917bc92fad 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/imports/JsOptimizeImportsTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/imports/JsOptimizeImportsTestGenerated.java @@ -501,6 +501,11 @@ public abstract class JsOptimizeImportsTestGenerated extends AbstractJsOptimizeI runTest("testData/editor/optimizeImports/common/ResolvedImportAndUnresolvedReference.kt"); } + @TestMetadata("SamConstructor_nestedClass.kt") + public void testSamConstructor_nestedClass() throws Exception { + runTest("testData/editor/optimizeImports/common/SamConstructor_nestedClass.kt"); + } + @TestMetadata("SeveralClasses.kt") public void testSeveralClasses() throws Exception { runTest("testData/editor/optimizeImports/common/SeveralClasses.kt"); @@ -531,6 +536,11 @@ public abstract class JsOptimizeImportsTestGenerated extends AbstractJsOptimizeI runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_annotation.kt"); } + @TestMetadata("TypeAliasedConstructor_samConstructor.kt") + public void testTypeAliasedConstructor_samConstructor() throws Exception { + runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt"); + } + @TestMetadata("TypeAliasedConstructor_sameName.kt") public void testTypeAliasedConstructor_sameName() throws Exception { runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_sameName.kt"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/imports/JvmOptimizeImportsTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/imports/JvmOptimizeImportsTestGenerated.java index 88a6ce0c5fc2..f51b769a8a7d 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/imports/JvmOptimizeImportsTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/imports/JvmOptimizeImportsTestGenerated.java @@ -769,6 +769,11 @@ public abstract class JvmOptimizeImportsTestGenerated extends AbstractJvmOptimiz runTest("testData/editor/optimizeImports/common/ResolvedImportAndUnresolvedReference.kt"); } + @TestMetadata("SamConstructor_nestedClass.kt") + public void testSamConstructor_nestedClass() throws Exception { + runTest("testData/editor/optimizeImports/common/SamConstructor_nestedClass.kt"); + } + @TestMetadata("SeveralClasses.kt") public void testSeveralClasses() throws Exception { runTest("testData/editor/optimizeImports/common/SeveralClasses.kt"); @@ -799,6 +804,11 @@ public abstract class JvmOptimizeImportsTestGenerated extends AbstractJvmOptimiz runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_annotation.kt"); } + @TestMetadata("TypeAliasedConstructor_samConstructor.kt") + public void testTypeAliasedConstructor_samConstructor() throws Exception { + runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt"); + } + @TestMetadata("TypeAliasedConstructor_sameName.kt") public void testTypeAliasedConstructor_sameName() throws Exception { runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_sameName.kt"); diff --git a/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/SamConstructor_nestedClass.kt b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/SamConstructor_nestedClass.kt new file mode 100644 index 000000000000..6b06c1accc98 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/SamConstructor_nestedClass.kt @@ -0,0 +1,13 @@ +package test + +import test.Outer.Nested + +class Outer { + fun interface Nested { + fun foo() + } +} + +fun usage() { + Nested {} +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/SamConstructor_nestedClass.kt.after b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/SamConstructor_nestedClass.kt.after new file mode 100644 index 000000000000..9d5fcaa07be9 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/SamConstructor_nestedClass.kt.after @@ -0,0 +1,13 @@ +package test + +import test.Outer.Nested + +class Outer { + fun interface Nested { + fun foo() + } +} + +fun usage() { + Nested {} +} diff --git a/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.dependency.kt b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.dependency.kt new file mode 100644 index 000000000000..5c581324bc51 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.dependency.kt @@ -0,0 +1,7 @@ +package dependency + +fun interface Foo { + fun bar() +} + +typealias TypeAliasedFoo = Foo \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt new file mode 100644 index 000000000000..acb539cc3035 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt @@ -0,0 +1,8 @@ +package test + +import dependency.Foo +import dependency.TypeAliasedFoo + +fun usage() { + TypeAliasedFoo {} +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt.after b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt.after new file mode 100644 index 000000000000..cacc39f3e9f8 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt.after @@ -0,0 +1,7 @@ +package test + +import dependency.TypeAliasedFoo + +fun usage() { + TypeAliasedFoo {} +}