From 93f1555322bf8c964416ab2e5f352f95e1b64273 Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Fri, 5 Jan 2024 15:13:50 +0100 Subject: [PATCH] KTIJ-28080 [AA] Move selection checking to `ElementsToShortenCollector.findClassifierQualifierToShorten` This way, even if the whole qualifier is not selected, but some of its parts are, the reference shortener will correctly find and shorten those parts ^KTIJ-28080 Fixed --- .../fir/components/KtFirReferenceShortener.kt | 25 ++++++++++++---- ...ModuleReferenceShortenerTestGenerated.java | 30 +++++++++++++++++++ ...ModuleReferenceShortenerTestGenerated.java | 30 +++++++++++++++++++ ...ootIdePackage_IsNotRemovedIfNotSelected.kt | 17 +++++++++++ ...otIdePackage_IsNotRemovedIfNotSelected.txt | 6 ++++ .../shortenRange/partiallySelectedType3.kt | 11 +++++++ .../shortenRange/partiallySelectedType3.txt | 9 ++++++ .../shortenRange/partiallySelectedType4.kt | 15 ++++++++++ .../shortenRange/partiallySelectedType4.txt | 10 +++++++ .../partiallySelectedTypeQualifier3.kt | 15 ++++++++++ .../partiallySelectedTypeQualifier3.txt | 9 ++++++ .../partiallySelectedTypeQualifier4.kt | 19 ++++++++++++ .../partiallySelectedTypeQualifier4.txt | 10 +++++++ 13 files changed, 201 insertions(+), 5 deletions(-) create mode 100644 analysis/analysis-api/testData/components/referenceShortener/shortenRange/_rootIdePackage_IsNotRemovedIfNotSelected.kt create mode 100644 analysis/analysis-api/testData/components/referenceShortener/shortenRange/_rootIdePackage_IsNotRemovedIfNotSelected.txt create mode 100644 analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType3.kt create mode 100644 analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType3.txt create mode 100644 analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType4.kt create mode 100644 analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType4.txt create mode 100644 analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier3.kt create mode 100644 analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier3.txt create mode 100644 analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier4.kt create mode 100644 analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier4.txt 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 f0ff01b7e77..6d3d9d5bc2f 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 @@ -524,8 +524,6 @@ private class ElementsToShortenCollector( val typeElement = resolvedTypeRef.correspondingTypePsi ?: return if (typeElement.qualifier == null) return - if (!typeElement.inSelection) return - val classifierId = resolvedTypeRef.type.lowerBoundIfFlexible().candidateClassId ?: return findTypeQualifierToShorten(classifierId, typeElement)?.let(::addElementToShorten) @@ -597,8 +595,6 @@ private class ElementsToShortenCollector( else -> return } - if (!wholeQualifierElement.inSelection) return - findTypeQualifierToShorten(wholeClassQualifier, wholeQualifierElement)?.let(::addElementToShorten) } @@ -829,6 +825,10 @@ private class ElementsToShortenCollector( /** * Finds the longest qualifier in [wholeQualifierElement] which can be safely shortened in the [positionScopes]. * [wholeQualifierClassId] is supposed to reflect the class which is referenced by the [wholeQualifierElement]. + * + * N.B. Even if the [wholeQualifierElement] is not strictly in the [selection], + * some outer part of it might be, and we want to shorten that. + * So we have to check all the outer qualifiers. */ private fun findClassifierQualifierToShorten( positionScopes: List, @@ -839,6 +839,8 @@ private class ElementsToShortenCollector( val allQualifiedElements = wholeQualifierElement.qualifiedElementsWithSelf for ((classId, element) in allClassIds.zip(allQualifiedElements)) { + if (!element.inSelection) continue + val classSymbol = shorteningContext.toClassSymbol(classId) ?: return null val option = classShortenStrategy(classSymbol) if (option == ShortenStrategy.DO_NOT_SHORTEN) continue @@ -885,7 +887,11 @@ private class ElementsToShortenCollector( } } } - return findFakePackageToShorten(allQualifiedElements.last()) + + val lastQualifier = allQualifiedElements.last() + if (!lastQualifier.inSelection) return null + + return findFakePackageToShorten(lastQualifier) } private fun createElementToShorten( @@ -1361,6 +1367,15 @@ private class ElementsToShortenCollector( } } + private val KtElement.inSelection: Boolean + get() = when (this) { + is KtUserType -> inSelection + is KtDotQualifiedExpression -> inSelection + is KtThisExpression -> inSelection + + else -> error("Unexpected ${this::class}") + } + /** * Checks whether type reference of [this] type is considered to be in the [selection] text range. * 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 b536873f5d2..a2ececbc56c 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 @@ -418,6 +418,18 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType2.kt"); } + @Test + @TestMetadata("partiallySelectedType3.kt") + public void testPartiallySelectedType3() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType3.kt"); + } + + @Test + @TestMetadata("partiallySelectedType4.kt") + public void testPartiallySelectedType4() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType4.kt"); + } + @Test @TestMetadata("partiallySelectedTypeQualifier1.kt") public void testPartiallySelectedTypeQualifier1() throws Exception { @@ -430,6 +442,18 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier2.kt"); } + @Test + @TestMetadata("partiallySelectedTypeQualifier3.kt") + public void testPartiallySelectedTypeQualifier3() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier3.kt"); + } + + @Test + @TestMetadata("partiallySelectedTypeQualifier4.kt") + public void testPartiallySelectedTypeQualifier4() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier4.kt"); + } + @Test @TestMetadata("qualifierOfUnresolvedReference.kt") public void testQualifierOfUnresolvedReference() throws Exception { @@ -628,6 +652,12 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/variable_invokeOperator.kt"); } + @Test + @TestMetadata("_rootIdePackage_IsNotRemovedIfNotSelected.kt") + public void test_rootIdePackage_IsNotRemovedIfNotSelected() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/_rootIdePackage_IsNotRemovedIfNotSelected.kt"); + } + @Nested @TestMetadata("analysis/analysis-api/testData/components/referenceShortener/shortenRange/nestedClasses") @TestDataPath("$PROJECT_ROOT") 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 7a5cf6f8eeb..921277f9ae0 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 @@ -418,6 +418,18 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType2.kt"); } + @Test + @TestMetadata("partiallySelectedType3.kt") + public void testPartiallySelectedType3() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType3.kt"); + } + + @Test + @TestMetadata("partiallySelectedType4.kt") + public void testPartiallySelectedType4() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType4.kt"); + } + @Test @TestMetadata("partiallySelectedTypeQualifier1.kt") public void testPartiallySelectedTypeQualifier1() throws Exception { @@ -430,6 +442,18 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier2.kt"); } + @Test + @TestMetadata("partiallySelectedTypeQualifier3.kt") + public void testPartiallySelectedTypeQualifier3() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier3.kt"); + } + + @Test + @TestMetadata("partiallySelectedTypeQualifier4.kt") + public void testPartiallySelectedTypeQualifier4() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier4.kt"); + } + @Test @TestMetadata("qualifierOfUnresolvedReference.kt") public void testQualifierOfUnresolvedReference() throws Exception { @@ -628,6 +652,12 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/variable_invokeOperator.kt"); } + @Test + @TestMetadata("_rootIdePackage_IsNotRemovedIfNotSelected.kt") + public void test_rootIdePackage_IsNotRemovedIfNotSelected() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/shortenRange/_rootIdePackage_IsNotRemovedIfNotSelected.kt"); + } + @Nested @TestMetadata("analysis/analysis-api/testData/components/referenceShortener/shortenRange/nestedClasses") @TestDataPath("$PROJECT_ROOT") diff --git a/analysis/analysis-api/testData/components/referenceShortener/shortenRange/_rootIdePackage_IsNotRemovedIfNotSelected.kt b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/_rootIdePackage_IsNotRemovedIfNotSelected.kt new file mode 100644 index 00000000000..f46c93478a2 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/_rootIdePackage_IsNotRemovedIfNotSelected.kt @@ -0,0 +1,17 @@ +// FILE: main.kt +package test + +fun usage( + foo: _root_ide_package_.dependency.Foo +) { + "random expr" + + _root_ide_package_.dependency.Foo.bar() +} + +// FILE: dependency.kt +package dependency + +object Foo { + fun bar() {} +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/referenceShortener/shortenRange/_rootIdePackage_IsNotRemovedIfNotSelected.txt b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/_rootIdePackage_IsNotRemovedIfNotSelected.txt new file mode 100644 index 00000000000..0d5b1b01292 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/_rootIdePackage_IsNotRemovedIfNotSelected.txt @@ -0,0 +1,6 @@ +Before shortening: "random expr" +with default settings: +with DO_NOT_SHORTEN: +with SHORTEN_IF_ALREADY_IMPORTED: +with SHORTEN_AND_IMPORT: +with SHORTEN_AND_STAR_IMPORT: diff --git a/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType3.kt b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType3.kt new file mode 100644 index 00000000000..bd4305b4f5d --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType3.kt @@ -0,0 +1,11 @@ +// FILE: main.kt +package test + +fun usage(foo: dependency.Foo.Bar) {} + +// FILE: dependency.kt +package dependency + +class Foo { + class Bar +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType3.txt b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType3.txt new file mode 100644 index 00000000000..fdd807f84cd --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType3.txt @@ -0,0 +1,9 @@ +Before shortening: dependency.Foo +with default settings: +[type] dependency.Foo +with DO_NOT_SHORTEN: +with SHORTEN_IF_ALREADY_IMPORTED: +with SHORTEN_AND_IMPORT: +[type] dependency.Foo +with SHORTEN_AND_STAR_IMPORT: +[type] dependency.Foo diff --git a/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType4.kt b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType4.kt new file mode 100644 index 00000000000..2eea11db502 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType4.kt @@ -0,0 +1,15 @@ +// FILE: main.kt +package test + +import dependency.Foo + +fun usage(foo: dependency.Foo.Bar.Baz) {} + +// FILE: dependency.kt +package dependency + +class Foo { + class Bar { + class Baz + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType4.txt b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType4.txt new file mode 100644 index 00000000000..116ada3308e --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedType4.txt @@ -0,0 +1,10 @@ +Before shortening: dependency.Foo.Bar +with default settings: +[type] dependency.Foo +with DO_NOT_SHORTEN: +with SHORTEN_IF_ALREADY_IMPORTED: +[type] dependency.Foo +with SHORTEN_AND_IMPORT: +[type] dependency.Foo.Bar +with SHORTEN_AND_STAR_IMPORT: +[type] dependency.Foo.Bar diff --git a/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier3.kt b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier3.kt new file mode 100644 index 00000000000..eb62b710aaf --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier3.kt @@ -0,0 +1,15 @@ +// FILE: main.kt +package test + +fun usage() { + dependency.Foo.Bar.baz() +} + +// FILE: dependency.kt +package dependency + +object Foo { + object Bar { + fun baz() {} + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier3.txt b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier3.txt new file mode 100644 index 00000000000..f32694a9c1e --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier3.txt @@ -0,0 +1,9 @@ +Before shortening: dependency.Foo +with default settings: +[qualifier] 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 diff --git a/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier4.kt b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier4.kt new file mode 100644 index 00000000000..90a81c8c270 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier4.kt @@ -0,0 +1,19 @@ +// FILE: main.kt +package test + +import dependency.Foo + +fun usage() { + dependency.Foo.Bar.Baz.qux() +} + +// FILE: dependency.kt +package dependency + +object Foo { + class Bar { + object Baz { + fun qux() {} + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier4.txt b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier4.txt new file mode 100644 index 00000000000..5cb9e1feec6 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/shortenRange/partiallySelectedTypeQualifier4.txt @@ -0,0 +1,10 @@ +Before shortening: dependency.Foo.Bar +with default settings: +[qualifier] dependency.Foo +with DO_NOT_SHORTEN: +with SHORTEN_IF_ALREADY_IMPORTED: +[qualifier] dependency.Foo +with SHORTEN_AND_IMPORT: +[qualifier] dependency.Foo.Bar +with SHORTEN_AND_STAR_IMPORT: +[qualifier] dependency.Foo.Bar