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 1cc22967872..8600c2bba00 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 @@ -133,12 +133,12 @@ private enum class ImportKind { /** Explicitly imported by user. */ EXPLICIT, - /** Explicitly imported by Kotlin default. For example, `kotlin.String`. */ - DEFAULT_EXPLICIT, - /** Implicitly imported from package. */ PACKAGE, + /** Explicitly imported by Kotlin default. For example, `kotlin.String`. */ + DEFAULT_EXPLICIT, + /** Star imported (star import) by user. */ STAR, @@ -158,6 +158,12 @@ private enum class ImportKind { else -> LOCAL } } + + fun fromShortenOption(option: ShortenOption): ImportKind? = when (option) { + ShortenOption.SHORTEN_AND_IMPORT -> EXPLICIT + ShortenOption.SHORTEN_AND_STAR_IMPORT -> STAR + else -> null + } } } @@ -974,10 +980,12 @@ private class ElementsToShortenCollector( val nameToImport = shorteningContext.convertToImportableName(calledSymbol) val (matchedCallables, otherCallables) = availableCallables.partition { it.symbol.callableId == calledSymbol.callableId } + + val importKindFromOption = ImportKind.fromShortenOption(option) + val importKind = matchedCallables.minOfOrNull { it.importKind } ?: importKindFromOption ?: return + val callToShorten = when { - // TODO: instead of allowing import only if the other callables are all with kind `DEFAULT_STAR`, we should allow import if - // the requested import kind has higher priority than the available symbols. - otherCallables.all { it.importKind == ImportKind.DEFAULT_STAR } -> { + otherCallables.all { importKind.hasHigherPriorityThan(it.importKind) } -> { when { matchedCallables.isEmpty() -> { if (nameToImport == null || option == ShortenOption.SHORTEN_IF_ALREADY_IMPORTED) return 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 73226637934..2824db60d7c 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 @@ -52,6 +52,24 @@ public class FirIdeNormalAnalysisSourceModuleReferenceShortenerTestGenerated ext runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/annotaiton.kt"); } + @Test + @TestMetadata("callableFromDefaultImport.kt") + public void testCallableFromDefaultImport() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport.kt"); + } + + @Test + @TestMetadata("callableFromDefaultImport2.kt") + public void testCallableFromDefaultImport2() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport2.kt"); + } + + @Test + @TestMetadata("callableFromExplicitImport.kt") + public void testCallableFromExplicitImport() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromExplicitImport.kt"); + } + @Test @TestMetadata("classScopes.kt") public void testClassScopes() 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 b4f0d1e5d1b..e8568fae4d0 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 @@ -52,6 +52,24 @@ public class FirStandaloneNormalAnalysisSourceModuleReferenceShortenerTestGenera runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/annotaiton.kt"); } + @Test + @TestMetadata("callableFromDefaultImport.kt") + public void testCallableFromDefaultImport() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport.kt"); + } + + @Test + @TestMetadata("callableFromDefaultImport2.kt") + public void testCallableFromDefaultImport2() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport2.kt"); + } + + @Test + @TestMetadata("callableFromExplicitImport.kt") + public void testCallableFromExplicitImport() throws Exception { + runTest("analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromExplicitImport.kt"); + } + @Test @TestMetadata("classScopes.kt") public void testClassScopes() throws Exception { diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport.kt new file mode 100644 index 00000000000..25b24c6ca6c --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport.kt @@ -0,0 +1,4 @@ +// WITH_STDLIB +// FILE: main.kt + +fun test() = kotlin.text.charset("") \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport.txt new file mode 100644 index 00000000000..9df827d6f23 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport.txt @@ -0,0 +1,8 @@ +Before shortening: kotlin.text.charset("") +with DO_NOT_SHORTEN: +with SHORTEN_IF_ALREADY_IMPORTED: +[qualifier] kotlin.text.charset("") +with SHORTEN_AND_IMPORT: +[qualifier] kotlin.text.charset("") +with SHORTEN_AND_STAR_IMPORT: +[qualifier] kotlin.text.charset("") diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport2.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport2.kt new file mode 100644 index 00000000000..ea7e6de1650 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport2.kt @@ -0,0 +1,7 @@ +// WITH_STDLIB +// FILE: main.kt +import java.nio.charset.Charset + +fun charset(charsetName: String): Charset = Charset.forName(charsetName) + +fun test() = kotlin.text.charset("") \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport2.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport2.txt new file mode 100644 index 00000000000..30d2da89264 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromDefaultImport2.txt @@ -0,0 +1,5 @@ +Before shortening: kotlin.text.charset("") +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/referenceShortener/callableFromExplicitImport.kt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromExplicitImport.kt new file mode 100644 index 00000000000..8c8da889db3 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromExplicitImport.kt @@ -0,0 +1,13 @@ +// FILE: main.kt +package a.b.c + +fun foo() {} + +fun test() { + dependency.foo() +} + +// FILE: dependency.kt +package dependency + +fun foo() {} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromExplicitImport.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromExplicitImport.txt new file mode 100644 index 00000000000..b0d061b6864 --- /dev/null +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/callableFromExplicitImport.txt @@ -0,0 +1,6 @@ +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: diff --git a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/companionUsedOutOfClass.txt b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/companionUsedOutOfClass.txt index 44c68ec071e..6808aa1a678 100644 --- a/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/companionUsedOutOfClass.txt +++ b/analysis/analysis-api/testData/components/referenceShortener/referenceShortener/companionUsedOutOfClass.txt @@ -3,6 +3,6 @@ with DO_NOT_SHORTEN: with SHORTEN_IF_ALREADY_IMPORTED: [qualifier] a.b.c.MyClass with SHORTEN_AND_IMPORT: -[qualifier] a.b.c.MyClass.Companion +[qualifier] a.b.c.MyClass.Companion.foo() with SHORTEN_AND_STAR_IMPORT: [qualifier] a.b.c.MyClass.Companion