From 0b8f4cc1e8adc0aaaa5b33da14fa45904c28d10a Mon Sep 17 00:00:00 2001 From: Andrew Kozlov Date: Tue, 3 Sep 2024 15:05:24 +0200 Subject: [PATCH] [kotlin] KTIJ-31100 proper rendering GitOrigin-RevId: 6e809ed88caa0193f4581f085b01a9246b304087 --- .../impl/k2/lookups/TailTextProvider.kt | 2 +- .../factories/TypeLookupElementFactory.kt | 48 ++++++++++++++----- .../InImportEscaped.dependency.kt | 3 ++ .../InImportEscaped/InImportEscaped.kt | 4 ++ .../handlers/multifile/InImportEscaped-1.kt | 1 + .../handlers/multifile/InImportEscaped-2.kt | 3 ++ .../multifile/InImportEscaped.kt.after | 3 ++ ...tiFileJvmBasicCompletionTestGenerated.java | 5 ++ .../AbstractCompletionMultiFileHandlerTest.kt | 1 + ...tiFileJvmBasicCompletionTestGenerated.java | 5 ++ 10 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 plugins/kotlin/completion/testData/basic/multifile/InImportEscaped/InImportEscaped.dependency.kt create mode 100644 plugins/kotlin/completion/testData/basic/multifile/InImportEscaped/InImportEscaped.kt create mode 100644 plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped-1.kt create mode 100644 plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped-2.kt create mode 100644 plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped.kt.after diff --git a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/lookups/TailTextProvider.kt b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/lookups/TailTextProvider.kt index c85b208aa9ce..6e2a0e948281 100644 --- a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/lookups/TailTextProvider.kt +++ b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/lookups/TailTextProvider.kt @@ -91,7 +91,7 @@ internal object TailTextProvider { } private fun FqName.asStringForTailText(): String = - if (isRoot) "" else asString() + if (isRoot) "" else render() context(KaSession) fun insertLambdaBraces(symbol: KaFunctionType): Boolean { diff --git a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/lookups/factories/TypeLookupElementFactory.kt b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/lookups/factories/TypeLookupElementFactory.kt index a965f01cf0da..092d53587fa0 100644 --- a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/lookups/factories/TypeLookupElementFactory.kt +++ b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/lookups/factories/TypeLookupElementFactory.kt @@ -5,13 +5,14 @@ import com.intellij.codeInsight.completion.InsertHandler import com.intellij.codeInsight.completion.InsertionContext import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElementBuilder +import com.intellij.openapi.util.NlsSafe +import org.jetbrains.annotations.NonNls import org.jetbrains.kotlin.analysis.api.KaExperimentalApi import org.jetbrains.kotlin.analysis.api.KaSession import org.jetbrains.kotlin.analysis.api.renderer.base.annotations.KaRendererAnnotationsFilter import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KaTypeRendererForSource import org.jetbrains.kotlin.analysis.api.symbols.KaClassLikeSymbol import org.jetbrains.kotlin.analysis.api.symbols.KaClassifierSymbol -import org.jetbrains.kotlin.analysis.api.symbols.KaTypeParameterSymbol import org.jetbrains.kotlin.analysis.api.types.KaFunctionType import org.jetbrains.kotlin.analysis.api.types.KaType import org.jetbrains.kotlin.analysis.api.types.KaTypeParameterType @@ -20,6 +21,8 @@ import org.jetbrains.kotlin.idea.KotlinIcons import org.jetbrains.kotlin.idea.completion.lookups.TailTextProvider.getTailText import org.jetbrains.kotlin.idea.completion.lookups.factories.insertAndShortenReferencesInStringUsingTemporarySuffix import org.jetbrains.kotlin.idea.completion.lookups.withClassifierSymbolInfo +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.renderer.render import org.jetbrains.kotlin.types.Variance internal object TypeLookupElementFactory { @@ -52,21 +55,34 @@ internal object TypeLookupElementFactory { context(KaSession) fun createLookup(symbol: KaClassifierSymbol): LookupElement? { - val (relativeNameAsString, fqNameAsString) = when (symbol) { - is KaTypeParameterSymbol -> symbol.name.asString().let { it to it } + val relativeName = symbol.name + ?: return null - is KaClassLikeSymbol -> when (val classId = symbol.classId) { - null -> symbol.name?.asString()?.let { it to it } - else -> classId.relativeClassName.asString() to classId.asFqNameString() - } - } ?: return null + val descriptor = when (symbol) { + is KaClassLikeSymbol -> symbol.classId + ?.let { (packageFqName, relativeClassName, _) -> + ClassDescriptor( + relativeClassName = relativeClassName, + renderedClassId = buildString { // see ClassId::asFqNameString + if (!packageFqName.isRoot) { + append(packageFqName.render()) + append(".") + } + append(relativeClassName.render()) + }, + tailText = getTailText(symbol, usePackageFqName = true), + ) + } - val tailText = (symbol as? KaClassLikeSymbol)?.let { getTailText(symbol, usePackageFqName = true) } + else -> null + } - return LookupElementBuilder.create(TypeLookupObject(fqNameAsString), relativeNameAsString) - .withInsertHandler(TypeInsertHandler) + return LookupElementBuilder.create( + /* lookupObject = */ TypeLookupObject(descriptor?.renderedClassId ?: relativeName.render()), + /* lookupString = */ descriptor?.relativeClassName?.asString() ?: relativeName.asString(), + ).withInsertHandler(TypeInsertHandler) .let { withClassifierSymbolInfo(symbol, it) } - .withTailText(tailText) + .withTailText(descriptor?.tailText) } private fun KaType.getSymbolIfTypeParameterOrUsualClass(): KaClassifierSymbol? = when (this) { @@ -93,4 +109,10 @@ private object TypeInsertHandler : InsertHandler { val lookupObject = item.`object` as TypeLookupObject context.insertAndShortenReferencesInStringUsingTemporarySuffix(lookupObject.fqRenderedType) } -} \ No newline at end of file +} + +private data class ClassDescriptor( + val relativeClassName: FqName, + val renderedClassId: @NonNls String, + val tailText: @NlsSafe String, +) \ No newline at end of file diff --git a/plugins/kotlin/completion/testData/basic/multifile/InImportEscaped/InImportEscaped.dependency.kt b/plugins/kotlin/completion/testData/basic/multifile/InImportEscaped/InImportEscaped.dependency.kt new file mode 100644 index 000000000000..7648d8d118bf --- /dev/null +++ b/plugins/kotlin/completion/testData/basic/multifile/InImportEscaped/InImportEscaped.dependency.kt @@ -0,0 +1,3 @@ +package `foo bar` + +class FooBar \ No newline at end of file diff --git a/plugins/kotlin/completion/testData/basic/multifile/InImportEscaped/InImportEscaped.kt b/plugins/kotlin/completion/testData/basic/multifile/InImportEscaped/InImportEscaped.kt new file mode 100644 index 000000000000..cba551efac23 --- /dev/null +++ b/plugins/kotlin/completion/testData/basic/multifile/InImportEscaped/InImportEscaped.kt @@ -0,0 +1,4 @@ +// IGNORE_K1 +fun bar(foo) + +// EXIST: { itemText: "fooBar: FooBar", tailText: " (`foo bar`)" } \ No newline at end of file diff --git a/plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped-1.kt b/plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped-1.kt new file mode 100644 index 000000000000..a810b5f770c1 --- /dev/null +++ b/plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped-1.kt @@ -0,0 +1 @@ +fun bar(fooBar) \ No newline at end of file diff --git a/plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped-2.kt b/plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped-2.kt new file mode 100644 index 000000000000..7648d8d118bf --- /dev/null +++ b/plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped-2.kt @@ -0,0 +1,3 @@ +package `foo bar` + +class FooBar \ No newline at end of file diff --git a/plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped.kt.after b/plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped.kt.after new file mode 100644 index 000000000000..2b2d3ba61766 --- /dev/null +++ b/plugins/kotlin/completion/testData/handlers/multifile/InImportEscaped.kt.after @@ -0,0 +1,3 @@ +import `foo bar`.FooBar + +fun bar(fooBar: FooBar) \ No newline at end of file diff --git a/plugins/kotlin/completion/tests-k1/test/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java b/plugins/kotlin/completion/tests-k1/test/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java index 5ee79c1769ea..5181dc9a8847 100644 --- a/plugins/kotlin/completion/tests-k1/test/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java +++ b/plugins/kotlin/completion/tests-k1/test/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java @@ -195,6 +195,11 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ runTest("../testData/basic/multifile/InImportCompanionObjectMembers/"); } + @TestMetadata("InImportEscaped") + public void testInImportEscaped() throws Exception { + runTest("../testData/basic/multifile/InImportEscaped/"); + } + @TestMetadata("InImportExtension") public void testInImportExtension() throws Exception { runTest("../testData/basic/multifile/InImportExtension/"); diff --git a/plugins/kotlin/completion/tests-shared/test/org/jetbrains/kotlin/idea/completion/test/handlers/AbstractCompletionMultiFileHandlerTest.kt b/plugins/kotlin/completion/tests-shared/test/org/jetbrains/kotlin/idea/completion/test/handlers/AbstractCompletionMultiFileHandlerTest.kt index 84ada68bdab0..716de8fdbb85 100644 --- a/plugins/kotlin/completion/tests-shared/test/org/jetbrains/kotlin/idea/completion/test/handlers/AbstractCompletionMultiFileHandlerTest.kt +++ b/plugins/kotlin/completion/tests-shared/test/org/jetbrains/kotlin/idea/completion/test/handlers/AbstractCompletionMultiFileHandlerTest.kt @@ -45,6 +45,7 @@ abstract class AbstractCompletionMultiFileHandlerTest : KotlinFixtureCompletionB fun testNotImportedTypeAlias() = doTest() fun testKT12077() = doTest() fun testClassInRootPackage() = doTest() + fun testInImportEscaped() = if (isFirPlugin) doTest(tailText = " (`foo bar`)") else Unit fun testPackageDirective() = if (isFirPlugin) doTest() else Unit fun testPackageInImportDirective() = if (isFirPlugin) doTest() else Unit diff --git a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/completion/HighLevelMultiFileJvmBasicCompletionTestGenerated.java b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/completion/HighLevelMultiFileJvmBasicCompletionTestGenerated.java index e800b8657595..45061d499bee 100644 --- a/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/completion/HighLevelMultiFileJvmBasicCompletionTestGenerated.java +++ b/plugins/kotlin/fir/tests/test/org/jetbrains/kotlin/idea/fir/completion/HighLevelMultiFileJvmBasicCompletionTestGenerated.java @@ -195,6 +195,11 @@ public class HighLevelMultiFileJvmBasicCompletionTestGenerated extends AbstractH runTest("../../completion/testData/basic/multifile/InImportCompanionObjectMembers/"); } + @TestMetadata("InImportEscaped") + public void testInImportEscaped() throws Exception { + runTest("../../completion/testData/basic/multifile/InImportEscaped/"); + } + @TestMetadata("InImportExtension") public void testInImportExtension() throws Exception { runTest("../../completion/testData/basic/multifile/InImportExtension/");