From 52d6ac5ed0fe29bde09b24bdde41950811afcebb Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Thu, 17 Aug 2023 21:26:52 +0200 Subject: [PATCH] [AA] Fix processing of member invoke functions from objects in reference shortening and import optimization Correctly handle `KtDotQualifedExpression`s with function calls as selectors (like `foo.Bar()`). Without such handling, processing of member invoke calls on objects was broken both for reference shortener (causing KTIJ-26695) and import optimizer (causing KTIJ-23407) Also, to fix KTIJ-23407, do not ignore qualifiers with `ImplicitInvokeCall` fake source ^KTIJ-26695 Fixed ^KTIJ-23407 Fixed --- ...leAnalysisApiImportOptimizerTestGenerated.java | 12 ++++++++++++ .../api/fir/components/KtFirImportOptimizer.kt | 7 ++++++- .../api/fir/components/KtFirReferenceShortener.kt | 5 ++--- ...leAnalysisApiImportOptimizerTestGenerated.java | 12 ++++++++++++ ...urceModuleReferenceShortenerTestGenerated.java | 6 ++++++ ...leAnalysisApiImportOptimizerTestGenerated.java | 12 ++++++++++++ ...urceModuleReferenceShortenerTestGenerated.java | 6 ++++++ .../unusedObject_invokeOperator.imports | 1 + .../analyseImports/unusedObject_invokeOperator.kt | 15 +++++++++++++++ .../usedObject_invokeOperator.imports | 0 .../analyseImports/usedObject_invokeOperator.kt | 15 +++++++++++++++ .../objectWithInvokeOperator.kt | 14 ++++++++++++++ .../objectWithInvokeOperator.txt | 7 +++++++ 13 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedObject_invokeOperator.imports create mode 100644 analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedObject_invokeOperator.kt create mode 100644 analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedObject_invokeOperator.imports create mode 100644 analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedObject_invokeOperator.kt create mode 100644 analysis/analysis-api/testData/components/referenceShortener/referenceShortener/objectWithInvokeOperator.kt create mode 100644 analysis/analysis-api/testData/components/referenceShortener/referenceShortener/objectWithInvokeOperator.txt diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/importOptimizer/Fe10IdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/importOptimizer/Fe10IdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java index a18f92585f7..c1ff94bad4d 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/importOptimizer/Fe10IdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/importOptimizer/Fe10IdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java @@ -118,6 +118,12 @@ public class Fe10IdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGene runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedInvokeOperatorImport.kt"); } + @Test + @TestMetadata("unusedObject_invokeOperator.kt") + public void testUnusedObject_invokeOperator() throws Exception { + runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedObject_invokeOperator.kt"); + } + @Test @TestMetadata("unusedStaticFunctionImportFromJavaChildClass.kt") public void testUnusedStaticFunctionImportFromJavaChildClass() throws Exception { @@ -214,6 +220,12 @@ public class Fe10IdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGene runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedInvokeOperatorImport.kt"); } + @Test + @TestMetadata("usedObject_invokeOperator.kt") + public void testUsedObject_invokeOperator() throws Exception { + runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedObject_invokeOperator.kt"); + } + @Test @TestMetadata("usedStaticFunctionImportFromJavaChildClass.kt") public void testUsedStaticFunctionImportFromJavaChildClass() throws Exception { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirImportOptimizer.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirImportOptimizer.kt index 29293e1442f..c13eb9dc125 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirImportOptimizer.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirImportOptimizer.kt @@ -500,7 +500,12 @@ private sealed interface TypeQualifier { companion object { val FirResolvedQualifier.isPresentInSource: Boolean - get() = source?.kind is KtRealSourceElementKind + get() = when (source?.kind) { + is KtRealSourceElementKind -> true + is KtFakeSourceElementKind.ImplicitInvokeCall -> true + + else -> false + } fun createFor(qualifier: FirResolvedQualifier): TypeQualifier? { if (!qualifier.isPresentInSource) return null diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt index 4813182cd6b..9a3958ab2bb 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirReferenceShortener.kt @@ -29,7 +29,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.resolver.AllCandidatesResolver -import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol import org.jetbrains.kotlin.fir.declarations.* @@ -1308,8 +1307,8 @@ private fun KtUserType.hasFakeRootPrefix(): Boolean = private fun KtDotQualifiedExpression.hasFakeRootPrefix(): Boolean = (receiverExpression as? KtNameReferenceExpression)?.getReferencedName() == ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE -internal fun KtElement.getDotQualifiedExpressionForSelector(): KtDotQualifiedExpression? = - getQualifiedExpressionForSelector() as? KtDotQualifiedExpression +internal fun KtSimpleNameExpression.getDotQualifiedExpressionForSelector(): KtDotQualifiedExpression? = + getQualifiedElement() as? KtDotQualifiedExpression private fun KtElement.getQualifier(): KtElement? = when (this) { is KtUserType -> qualifier diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/importOptimizer/FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/importOptimizer/FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java index bbdc628aaf6..02f29d8646c 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/importOptimizer/FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/importOptimizer/FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java @@ -118,6 +118,12 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGener runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedInvokeOperatorImport.kt"); } + @Test + @TestMetadata("unusedObject_invokeOperator.kt") + public void testUnusedObject_invokeOperator() throws Exception { + runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedObject_invokeOperator.kt"); + } + @Test @TestMetadata("unusedStaticFunctionImportFromJavaChildClass.kt") public void testUnusedStaticFunctionImportFromJavaChildClass() throws Exception { @@ -214,6 +220,12 @@ public class FirIdeNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGener runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedInvokeOperatorImport.kt"); } + @Test + @TestMetadata("usedObject_invokeOperator.kt") + public void testUsedObject_invokeOperator() throws Exception { + runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedObject_invokeOperator.kt"); + } + @Test @TestMetadata("usedStaticFunctionImportFromJavaChildClass.kt") public void testUsedStaticFunctionImportFromJavaChildClass() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java index 7fb604e04e9..582be5e8031 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/references/FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java @@ -316,6 +316,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClass3.kt"); } + @Test + @TestMetadata("objectWithInvokeOperator.kt") + public void testObjectWithInvokeOperator() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/objectWithInvokeOperator.kt"); + } + @Test @TestMetadata("parameterTypeTopLevelTypeLoses.kt") public void testParameterTypeTopLevelTypeLoses() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/importOptimizer/FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/importOptimizer/FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java index 5b5080b694b..96c57d67a57 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/importOptimizer/FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/importOptimizer/FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTestGenerated.java @@ -118,6 +118,12 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTe runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedInvokeOperatorImport.kt"); } + @Test + @TestMetadata("unusedObject_invokeOperator.kt") + public void testUnusedObject_invokeOperator() throws Exception { + runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedObject_invokeOperator.kt"); + } + @Test @TestMetadata("unusedStaticFunctionImportFromJavaChildClass.kt") public void testUnusedStaticFunctionImportFromJavaChildClass() throws Exception { @@ -214,6 +220,12 @@ public class FirStandaloneNormalAnalysisSourceModuleAnalysisApiImportOptimizerTe runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedInvokeOperatorImport.kt"); } + @Test + @TestMetadata("usedObject_invokeOperator.kt") + public void testUsedObject_invokeOperator() throws Exception { + runTest("analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedObject_invokeOperator.kt"); + } + @Test @TestMetadata("usedStaticFunctionImportFromJavaChildClass.kt") public void testUsedStaticFunctionImportFromJavaChildClass() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java index feb042afa55..2db1f48ced4 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/references/FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenerated.java @@ -316,6 +316,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/nestedClass3.kt"); } + @Test + @TestMetadata("objectWithInvokeOperator.kt") + public void testObjectWithInvokeOperator() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/objectWithInvokeOperator.kt"); + } + @Test @TestMetadata("parameterTypeTopLevelTypeLoses.kt") public void testParameterTypeTopLevelTypeLoses() throws Exception { diff --git a/analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedObject_invokeOperator.imports b/analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedObject_invokeOperator.imports new file mode 100644 index 00000000000..01b06c733fd --- /dev/null +++ b/analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedObject_invokeOperator.imports @@ -0,0 +1 @@ +dependency.MyObject diff --git a/analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedObject_invokeOperator.kt b/analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedObject_invokeOperator.kt new file mode 100644 index 00000000000..b72a7e7cf85 --- /dev/null +++ b/analysis/analysis-api/testData/components/importOptimizer/analyseImports/unusedObject_invokeOperator.kt @@ -0,0 +1,15 @@ +// FILE: main.kt +package test + +import dependency.MyObject + +fun usage() { + dependency.MyObject() +} + +// FILE: dependency.kt +package dependency + +object MyObject { + operator fun invoke() {} +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedObject_invokeOperator.imports b/analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedObject_invokeOperator.imports new file mode 100644 index 00000000000..e69de29bb2d diff --git a/analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedObject_invokeOperator.kt b/analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedObject_invokeOperator.kt new file mode 100644 index 00000000000..52e8067ff04 --- /dev/null +++ b/analysis/analysis-api/testData/components/importOptimizer/analyseImports/usedObject_invokeOperator.kt @@ -0,0 +1,15 @@ +// FILE: main.kt +package test + +import dependency.MyObject + +fun usage() { + MyObject() +} + +// FILE: dependency.kt +package dependency + +object MyObject { + operator fun invoke() {} +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/objectWithInvokeOperator.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/objectWithInvokeOperator.kt new file mode 100644 index 00000000000..5150925d92a --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/objectWithInvokeOperator.kt @@ -0,0 +1,14 @@ +// FILE: main.kt +package test + +fun test() { + dependency.Foo() +} + +// FILE: dependency.kt +package dependency + +object Foo { + operator fun invoke() {} +} + diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/objectWithInvokeOperator.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/objectWithInvokeOperator.txt new file mode 100644 index 00000000000..4a5ea8ba21d --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/objectWithInvokeOperator.txt @@ -0,0 +1,7 @@ +Before shortening: dependency.Foo() +with DO_NOT_SHORTEN: +with SHORTEN_IF_ALREADY_IMPORTED: +with SHORTEN_AND_IMPORT: +[qualifier] dependency.Foo() +with SHORTEN_AND_STAR_IMPORT: +[qualifier] dependency.Foo()