[Analysis API] KTIJ-23588 Do not ignore calls qualified with objects
^KTIJ-23588 Fixed
This commit is contained in:
+27
-5
@@ -174,7 +174,7 @@ internal class KtFirImportOptimizer(
|
||||
}
|
||||
|
||||
private fun processFunctionCall(functionCall: FirFunctionCall) {
|
||||
if (functionCall.isFullyQualified) return
|
||||
if (functionCall.dispatchedWithoutImport) return
|
||||
processErrorNameReference(functionCall)
|
||||
|
||||
val referencesByName = functionCall.functionReferenceName ?: return
|
||||
@@ -192,7 +192,7 @@ internal class KtFirImportOptimizer(
|
||||
}
|
||||
|
||||
private fun processPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression) {
|
||||
if (propertyAccessExpression.isFullyQualified) return
|
||||
if (propertyAccessExpression.dispatchedWithoutImport) return
|
||||
processErrorNameReference(propertyAccessExpression)
|
||||
|
||||
val referencedByName = propertyAccessExpression.propertyReferenceName ?: return
|
||||
@@ -208,7 +208,7 @@ internal class KtFirImportOptimizer(
|
||||
}
|
||||
|
||||
private fun processCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess) {
|
||||
if (callableReferenceAccess.isFullyQualified) return
|
||||
if (callableReferenceAccess.dispatchedWithoutImport) return
|
||||
processErrorNameReference(callableReferenceAccess)
|
||||
|
||||
val referencedByName = callableReferenceAccess.callableReferenceName ?: return
|
||||
@@ -331,8 +331,30 @@ private val FirResolvedTypeRef.resolvedClassId: ClassId?
|
||||
return singleClassSymbol?.classId
|
||||
}
|
||||
|
||||
private val FirQualifiedAccessExpression.isFullyQualified: Boolean
|
||||
get() = explicitReceiver is FirResolvedQualifier
|
||||
private val FirQualifiedAccessExpression.dispatchedWithoutImport: Boolean
|
||||
get() = when {
|
||||
isQualifiedWithPackage -> true
|
||||
dispatchReceiver is FirThisReceiverExpression -> true
|
||||
dispatchReceiver == explicitReceiver -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns `true` if [this] expression is fully-qualified with package name.
|
||||
* Such expressions definitely do not need any kind of imports.
|
||||
*
|
||||
* Examples:
|
||||
* - `pkg.foo()` - `true`
|
||||
* - `foo()` - `false`
|
||||
* - `Obj.foo()` - `false`
|
||||
* - `pkg.Obj.foo()` - `false`
|
||||
*/
|
||||
private val FirQualifiedAccessExpression.isQualifiedWithPackage: Boolean
|
||||
get() {
|
||||
val receiver = explicitReceiver
|
||||
return receiver is FirResolvedQualifier && receiver.relativeClassFqName == null
|
||||
}
|
||||
|
||||
private fun KtExpression.getPossiblyQualifiedSimpleNameExpression(): KtSimpleNameExpression? {
|
||||
return ((this as? KtQualifiedExpression)?.selectorExpression ?: this) as? KtSimpleNameExpression?
|
||||
|
||||
+30
@@ -58,6 +58,12 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGener
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedAliasedTypeImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedExtensionFunctionFromObject_implicitReceiver.kt")
|
||||
public void testUnusedExtensionFunctionFromObject_implicitReceiver() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedExtensionFunctionFromObject_implicitReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedFunctionImports.kt")
|
||||
public void testUnusedFunctionImports() throws Exception {
|
||||
@@ -70,6 +76,12 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGener
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedGenericTypeQualifier.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedImportFromObject.kt")
|
||||
public void testUnusedImportFromObject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedImportFromObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedInvokeOperatorImport.kt")
|
||||
public void testUnusedInvokeOperatorImport() throws Exception {
|
||||
@@ -88,6 +100,18 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGener
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedAliasedTypeImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("usedExtensionFunctionFromObject_implicitReceiver.kt")
|
||||
public void testUsedExtensionFunctionFromObject_implicitReceiver() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedExtensionFunctionFromObject_implicitReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("usedExtensionFunction_objectReceiver.kt")
|
||||
public void testUsedExtensionFunction_objectReceiver() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedExtensionFunction_objectReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("usedFunctionImport.kt")
|
||||
public void testUsedFunctionImport() throws Exception {
|
||||
@@ -100,6 +124,12 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGener
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedGenericTypeQualifier.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("usedImportFromObject.kt")
|
||||
public void testUsedImportFromObject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedImportFromObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("usedInvokeOperatorAliasedImport.kt")
|
||||
public void testUsedInvokeOperatorAliasedImport() throws Exception {
|
||||
|
||||
+30
@@ -58,6 +58,12 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTe
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedAliasedTypeImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedExtensionFunctionFromObject_implicitReceiver.kt")
|
||||
public void testUnusedExtensionFunctionFromObject_implicitReceiver() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedExtensionFunctionFromObject_implicitReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedFunctionImports.kt")
|
||||
public void testUnusedFunctionImports() throws Exception {
|
||||
@@ -70,6 +76,12 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTe
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedGenericTypeQualifier.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedImportFromObject.kt")
|
||||
public void testUnusedImportFromObject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedImportFromObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unusedInvokeOperatorImport.kt")
|
||||
public void testUnusedInvokeOperatorImport() throws Exception {
|
||||
@@ -88,6 +100,18 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTe
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedAliasedTypeImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("usedExtensionFunctionFromObject_implicitReceiver.kt")
|
||||
public void testUsedExtensionFunctionFromObject_implicitReceiver() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedExtensionFunctionFromObject_implicitReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("usedExtensionFunction_objectReceiver.kt")
|
||||
public void testUsedExtensionFunction_objectReceiver() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedExtensionFunction_objectReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("usedFunctionImport.kt")
|
||||
public void testUsedFunctionImport() throws Exception {
|
||||
@@ -100,6 +124,12 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTe
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedGenericTypeQualifier.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("usedImportFromObject.kt")
|
||||
public void testUsedImportFromObject() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedImportFromObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("usedInvokeOperatorAliasedImport.kt")
|
||||
public void testUsedInvokeOperatorAliasedImport() throws Exception {
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
dependency.Bar.extFun
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// FILE: main.kt
|
||||
package test
|
||||
|
||||
import dependency.Bar.extFun
|
||||
|
||||
fun usage() {
|
||||
with(dependency.Bar) {
|
||||
with(10) {
|
||||
extFun()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: dependency.kt
|
||||
package dependency
|
||||
|
||||
object Bar {
|
||||
fun Int.extFun() {}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
dependency.Bar.callable
|
||||
dependency.Bar.function
|
||||
dependency.Bar.property
|
||||
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
// FILE: main.kt
|
||||
import dependency.Bar.property
|
||||
import dependency.Bar.function
|
||||
import dependency.Bar.callable
|
||||
|
||||
fun test() {
|
||||
dependency.Bar.property
|
||||
dependency.Bar.function()
|
||||
dependency.Bar::callable
|
||||
|
||||
with(dependency.Bar) {
|
||||
property
|
||||
function()
|
||||
::callable
|
||||
}
|
||||
|
||||
val bar = dependency.Bar
|
||||
bar.property
|
||||
bar.function()
|
||||
bar::callable
|
||||
}
|
||||
|
||||
// FILE: dependency.kt
|
||||
package dependency
|
||||
|
||||
object Bar {
|
||||
val property: Int = 10
|
||||
fun function() {}
|
||||
fun callable() {}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// FILE: main.kt
|
||||
package test
|
||||
|
||||
import dependency.Bar.extFun
|
||||
|
||||
fun usage() {
|
||||
with(10) {
|
||||
extFun()
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: dependency.kt
|
||||
package dependency
|
||||
|
||||
object Bar {
|
||||
fun Int.extFun() {}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// FILE: main.kt
|
||||
package test
|
||||
|
||||
import dependency.Bar
|
||||
import dependency.extFun
|
||||
import dependency.extVal
|
||||
import dependency.extCallable
|
||||
|
||||
fun usage() {
|
||||
Bar.extFun()
|
||||
|
||||
Bar.extVal
|
||||
|
||||
val ref = Bar::extCallable
|
||||
}
|
||||
|
||||
// FILE: dependency.kt
|
||||
package dependency
|
||||
|
||||
object Bar
|
||||
|
||||
fun Bar.extFun() {}
|
||||
|
||||
val Bar.extVal: Int get() = 10
|
||||
|
||||
fun Bar.extCallable() {}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// FILE: main.kt
|
||||
import dependency.Bar.property
|
||||
import dependency.Bar.function
|
||||
import dependency.Bar.callable
|
||||
|
||||
fun test() {
|
||||
property
|
||||
function()
|
||||
::callable
|
||||
}
|
||||
|
||||
// FILE: dependency.kt
|
||||
package dependency
|
||||
|
||||
object Bar {
|
||||
val property: Int = 10
|
||||
fun function() {}
|
||||
fun callable() {}
|
||||
}
|
||||
Reference in New Issue
Block a user