[FIR IDE] Properly handle generic types qualifiers

In code like `foo.Bar<Bazz>`, `Bar<Bazz>` is considered to be
`KtCallExpression` from the PSI point

^KT-52779 Fixed
This commit is contained in:
Roman Golyshev
2022-06-14 16:02:26 +04:00
committed by teamcity
parent 90754d11c1
commit 4d6b424280
7 changed files with 68 additions and 5 deletions
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
import org.jetbrains.kotlin.psi.psiUtil.getPossiblyQualifiedCallExpression
import org.jetbrains.kotlin.psi.psiUtil.unwrapNullability
import org.jetbrains.kotlin.resolve.ImportPath
import org.jetbrains.kotlin.resolve.calls.util.getCalleeExpressionIfAny
import org.jetbrains.kotlin.util.OperatorNameConventions
internal class KtFirImportOptimizer(
@@ -323,11 +324,14 @@ private sealed interface TypeQualifier {
private val dotQualifier: KtDotQualifiedExpression? = qualifier as? KtDotQualifiedExpression
private val typeNameReference: KtNameReferenceExpression = when (qualifier) {
is KtDotQualifiedExpression -> qualifier.selectorExpression as? KtNameReferenceExpression
is KtNameReferenceExpression -> qualifier
else -> null
} ?: error("Cannot get referenced name from '${qualifier.text}'")
private val typeNameReference: KtNameReferenceExpression = run {
require(qualifier is KtNameReferenceExpression || qualifier is KtDotQualifiedExpression || qualifier is KtCallExpression) {
"Unexpected qualifier '${qualifier.text}' of type '${qualifier::class}'"
}
qualifier.getCalleeExpressionIfAny() as? KtNameReferenceExpression
?: error("Cannot get referenced name from '${qualifier.text}'")
}
override val referencedByName: Name
get() = typeNameReference.getReferencedNameAsName()
@@ -58,6 +58,12 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGener
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedFunctionImports.kt");
}
@Test
@TestMetadata("unusedGenericTypeQualifier.kt")
public void testUnusedGenericTypeQualifier() throws Exception {
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedGenericTypeQualifier.kt");
}
@Test
@TestMetadata("unusedInvokeOperatorImport.kt")
public void testUnusedInvokeOperatorImport() throws Exception {
@@ -82,6 +88,12 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGener
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedFunctionImport.kt");
}
@Test
@TestMetadata("usedGenericTypeQualifier.kt")
public void testUsedGenericTypeQualifier() throws Exception {
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedGenericTypeQualifier.kt");
}
@Test
@TestMetadata("usedInvokeOperatorAliasedImport.kt")
public void testUsedInvokeOperatorAliasedImport() throws Exception {
@@ -58,6 +58,12 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTe
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedFunctionImports.kt");
}
@Test
@TestMetadata("unusedGenericTypeQualifier.kt")
public void testUnusedGenericTypeQualifier() throws Exception {
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedGenericTypeQualifier.kt");
}
@Test
@TestMetadata("unusedInvokeOperatorImport.kt")
public void testUnusedInvokeOperatorImport() throws Exception {
@@ -82,6 +88,12 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTe
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedFunctionImport.kt");
}
@Test
@TestMetadata("usedGenericTypeQualifier.kt")
public void testUsedGenericTypeQualifier() throws Exception {
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedGenericTypeQualifier.kt");
}
@Test
@TestMetadata("usedInvokeOperatorAliasedImport.kt")
public void testUsedInvokeOperatorAliasedImport() throws Exception {
@@ -0,0 +1,17 @@
// FILE: main.kt
package test
import dependency.Bar
class MyClass
fun usage() {
val a = dependency.Bar<MyClass>::foo
}
// FILE: dependency.kt
package dependency
class Bar<T> {
fun foo() {}
}
@@ -0,0 +1,17 @@
// FILE: main.kt
package test
import dependency.Bar
class MyClass
fun usage() {
val a = Bar<MyClass>::foo
}
// FILE: dependency.kt
package dependency
class Bar<T> {
fun foo() {}
}