From 91cfd7fca035e19251379f0c886a320d0496d54d Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Mon, 3 Feb 2025 20:49:02 +0100 Subject: [PATCH] KTIJ-31122 [kotlin] Account for possible required type arguments in typealiased constructors calls Typealiased SAM constructors are still not properly resolved by Analysis API, see KT-68984. However, `resolveTypeAliasedConstructorReference` (which is designed to overcome this) had a problem with SAM typealiases with generic parameters due to missing required type arguments in the type references created by `resolveReferencedType`. By using `KaClassErrorType`'s `candidateSymbols`, this problem is now solved. This fix is specifically done before KTIJ-32955 fix is applied across all `intellij.git` repo, so that there is no need to suppress any false positives related to unused imports. ^KTIJ-31122 Fixed GitOrigin-RevId: 6241a224c41685a02ab516371ccf552b3a1bedb4 --- .../idea/k2/codeinsight/imports/resolveUtils.kt | 16 +++++++++++++--- .../K2JsOptimizeImportsTestGenerated.java | 10 ++++++++++ .../K2JvmOptimizeImportsTestGenerated.java | 10 ++++++++++ .../imports/JsOptimizeImportsTestGenerated.java | 10 ++++++++++ .../imports/JvmOptimizeImportsTestGenerated.java | 10 ++++++++++ ...tor_samConstructor_withGenerics.dependency.kt | 7 +++++++ ...sedConstructor_samConstructor_withGenerics.kt | 8 ++++++++ ...structor_samConstructor_withGenerics.kt.after | 7 +++++++ ...AliasedConstructor_withGenerics.dependency.kt | 5 +++++ .../TypeAliasedConstructor_withGenerics.kt | 8 ++++++++ .../TypeAliasedConstructor_withGenerics.kt.after | 7 +++++++ 11 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.dependency.kt create mode 100644 plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt create mode 100644 plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.dependency.kt create mode 100644 plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt create mode 100644 plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt.after diff --git a/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/imports/resolveUtils.kt b/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/imports/resolveUtils.kt index 71cf76129018..33ae16949325 100644 --- a/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/imports/resolveUtils.kt +++ b/plugins/kotlin/code-insight/kotlin.code-insight.k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/imports/resolveUtils.kt @@ -5,6 +5,7 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiMember import org.jetbrains.kotlin.analysis.api.KaSession import org.jetbrains.kotlin.analysis.api.symbols.* +import org.jetbrains.kotlin.analysis.api.types.KaClassErrorType import org.jetbrains.kotlin.analysis.api.types.KaType import org.jetbrains.kotlin.analysis.api.types.symbol import org.jetbrains.kotlin.idea.references.KtReference @@ -47,11 +48,20 @@ internal fun KaSession.resolveTypeAliasedConstructorReference( if (!typeAliasIsAvailable(originalReferenceName, containingFile)) return null val referencedType = resolveReferencedType(reference) ?: return null - if (referencedType.symbol != expandedClassSymbol) return null - val typealiasType = referencedType.abbreviation ?: return null + if (referencedType !is KaClassErrorType) { + if (referencedType.symbol != expandedClassSymbol) return null - return typealiasType.symbol + val typealiasType = referencedType.abbreviation ?: return null + + return typealiasType.symbol + } else { + val singleCandidate = referencedType.candidateSymbols.singleOrNull() as? KaTypeAliasSymbol?: return null + + if (singleCandidate.expandedType.symbol != expandedClassSymbol) return null + + return singleCandidate + } } private fun KaSession.typeAliasIsAvailable(name: Name, containingFile: KtFile): Boolean { diff --git a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/K2JsOptimizeImportsTestGenerated.java b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/K2JsOptimizeImportsTestGenerated.java index 78ca13ea5231..3cc7ee365668 100644 --- a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/K2JsOptimizeImportsTestGenerated.java +++ b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/K2JsOptimizeImportsTestGenerated.java @@ -661,11 +661,21 @@ public abstract class K2JsOptimizeImportsTestGenerated extends AbstractK2JsOptim runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt"); } + @TestMetadata("TypeAliasedConstructor_samConstructor_withGenerics.kt") + public void testTypeAliasedConstructor_samConstructor_withGenerics() throws Exception { + runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt"); + } + @TestMetadata("TypeAliasedConstructor_sameName.kt") public void testTypeAliasedConstructor_sameName() throws Exception { runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_sameName.kt"); } + @TestMetadata("TypeAliasedConstructor_withGenerics.kt") + public void testTypeAliasedConstructor_withGenerics() throws Exception { + runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt"); + } + @TestMetadata("UnresolvedImport.kt") public void testUnresolvedImport() throws Exception { runTest("../../idea/tests/testData/editor/optimizeImports/common/UnresolvedImport.kt"); diff --git a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/K2JvmOptimizeImportsTestGenerated.java b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/K2JvmOptimizeImportsTestGenerated.java index f9168765eb4a..74f021dd6aa9 100644 --- a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/K2JvmOptimizeImportsTestGenerated.java +++ b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/imports/K2JvmOptimizeImportsTestGenerated.java @@ -969,11 +969,21 @@ public abstract class K2JvmOptimizeImportsTestGenerated extends AbstractK2JvmOpt runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt"); } + @TestMetadata("TypeAliasedConstructor_samConstructor_withGenerics.kt") + public void testTypeAliasedConstructor_samConstructor_withGenerics() throws Exception { + runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt"); + } + @TestMetadata("TypeAliasedConstructor_sameName.kt") public void testTypeAliasedConstructor_sameName() throws Exception { runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_sameName.kt"); } + @TestMetadata("TypeAliasedConstructor_withGenerics.kt") + public void testTypeAliasedConstructor_withGenerics() throws Exception { + runTest("../../idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt"); + } + @TestMetadata("UnresolvedImport.kt") public void testUnresolvedImport() throws Exception { runTest("../../idea/tests/testData/editor/optimizeImports/common/UnresolvedImport.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 97a33d496727..e54abb64df2e 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 @@ -661,11 +661,21 @@ public abstract class JsOptimizeImportsTestGenerated extends AbstractJsOptimizeI runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt"); } + @TestMetadata("TypeAliasedConstructor_samConstructor_withGenerics.kt") + public void testTypeAliasedConstructor_samConstructor_withGenerics() throws Exception { + runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt"); + } + @TestMetadata("TypeAliasedConstructor_sameName.kt") public void testTypeAliasedConstructor_sameName() throws Exception { runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_sameName.kt"); } + @TestMetadata("TypeAliasedConstructor_withGenerics.kt") + public void testTypeAliasedConstructor_withGenerics() throws Exception { + runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt"); + } + @TestMetadata("UnresolvedImport.kt") public void testUnresolvedImport() throws Exception { runTest("testData/editor/optimizeImports/common/UnresolvedImport.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 b60ea8e1a854..03f5adf7b7cc 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 @@ -974,11 +974,21 @@ public abstract class JvmOptimizeImportsTestGenerated extends AbstractJvmOptimiz runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor.kt"); } + @TestMetadata("TypeAliasedConstructor_samConstructor_withGenerics.kt") + public void testTypeAliasedConstructor_samConstructor_withGenerics() throws Exception { + runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt"); + } + @TestMetadata("TypeAliasedConstructor_sameName.kt") public void testTypeAliasedConstructor_sameName() throws Exception { runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_sameName.kt"); } + @TestMetadata("TypeAliasedConstructor_withGenerics.kt") + public void testTypeAliasedConstructor_withGenerics() throws Exception { + runTest("testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt"); + } + @TestMetadata("UnresolvedImport.kt") public void testUnresolvedImport() throws Exception { runTest("testData/editor/optimizeImports/common/UnresolvedImport.kt"); diff --git a/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.dependency.kt b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.dependency.kt new file mode 100644 index 000000000000..91add8e78421 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.dependency.kt @@ -0,0 +1,7 @@ +package dependency + +fun interface Foo { + fun bar(): T +} + +typealias TypeAliasedFoo = Foo \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt new file mode 100644 index 000000000000..9c423ac61b20 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt @@ -0,0 +1,8 @@ +package test + +import dependency.Foo +import dependency.TypeAliasedFoo + +fun usage() { + TypeAliasedFoo { "hello" } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt.after b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt.after new file mode 100644 index 000000000000..716ca60a5b00 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_samConstructor_withGenerics.kt.after @@ -0,0 +1,7 @@ +package test + +import dependency.TypeAliasedFoo + +fun usage() { + TypeAliasedFoo { "hello" } +} diff --git a/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.dependency.kt b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.dependency.kt new file mode 100644 index 000000000000..cbf4041897b2 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.dependency.kt @@ -0,0 +1,5 @@ +package dependency + +class Foo(t: T) + +typealias TypeAliasedFoo = Foo \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt new file mode 100644 index 000000000000..f7e36cdf26a9 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt @@ -0,0 +1,8 @@ +package test + +import dependency.Foo +import dependency.TypeAliasedFoo + +fun usage() { + TypeAliasedFoo("hello") +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt.after b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt.after new file mode 100644 index 000000000000..9a7fd0090de5 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/editor/optimizeImports/common/TypeAliasedConstructor_withGenerics.kt.after @@ -0,0 +1,7 @@ +package test + +import dependency.TypeAliasedFoo + +fun usage() { + TypeAliasedFoo("hello") +}