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
This commit is contained in:
Roman Golyshev
2025-02-03 22:05:13 +00:00
committed by intellij-monorepo-bot
parent 07d80d7d06
commit 91cfd7fca0
11 changed files with 95 additions and 3 deletions
@@ -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 {
@@ -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");
@@ -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");
@@ -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");
@@ -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");
@@ -0,0 +1,7 @@
package dependency
fun interface Foo<T> {
fun bar(): T
}
typealias TypeAliasedFoo<Param> = Foo<Param>
@@ -0,0 +1,8 @@
package test
import dependency.Foo
import dependency.TypeAliasedFoo
fun usage() {
TypeAliasedFoo { "hello" }
}
@@ -0,0 +1,7 @@
package test
import dependency.TypeAliasedFoo
fun usage() {
TypeAliasedFoo { "hello" }
}
@@ -0,0 +1,5 @@
package dependency
class Foo<T>(t: T)
typealias TypeAliasedFoo<Param> = Foo<Param>
@@ -0,0 +1,8 @@
package test
import dependency.Foo
import dependency.TypeAliasedFoo
fun usage() {
TypeAliasedFoo("hello")
}
@@ -0,0 +1,7 @@
package test
import dependency.TypeAliasedFoo
fun usage() {
TypeAliasedFoo("hello")
}