diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/KotlinCallableLookupObject.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/KotlinCallableLookupObject.kt new file mode 100644 index 00000000000..678aab3760a --- /dev/null +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/KotlinCallableLookupObject.kt @@ -0,0 +1,10 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.completion.lookups + +abstract class KotlinCallableLookupObject: KotlinLookupObject { + abstract val renderedReceiverType: String? +} \ No newline at end of file diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/TailTextProvider.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/TailTextProvider.kt new file mode 100644 index 00000000000..7fe87aa8167 --- /dev/null +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/TailTextProvider.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.completion.lookups + +import org.jetbrains.kotlin.idea.completion.KotlinIdeaCompletionBundle +import org.jetbrains.kotlin.idea.completion.lookups.CompletionShortNamesRenderer.renderFunctionParameters +import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol +import org.jetbrains.kotlin.idea.frontend.api.types.KtFunctionalType + +internal object TailTextProvider { + fun KtAnalysisSession.getTailText(symbol: KtCallableSymbol): String = buildString { + if (symbol is KtFunctionSymbol) { + if (insertLambdaBraces(symbol)) { + append(" {...}") + } else { + append(renderFunctionParameters(symbol)) + } + } + symbol.receiverType?.type?.let{ receiverType -> + val renderedType = receiverType.render(CompletionShortNamesRenderer.TYPE_RENDERING_OPTIONS) + append(KotlinIdeaCompletionBundle.message("presentation.tail.for.0", renderedType)) + } + } + + fun KtAnalysisSession.insertLambdaBraces(symbol: KtFunctionSymbol): Boolean { + val singleParam = symbol.valueParameters.singleOrNull() + return singleParam != null && !singleParam.hasDefaultValue && singleParam.annotatedType.type is KtFunctionalType + } +} \ No newline at end of file diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/factories/FunctionLookupElementFactory.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/factories/FunctionLookupElementFactory.kt index 9f798238aec..b49d542f186 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/factories/FunctionLookupElementFactory.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/factories/FunctionLookupElementFactory.kt @@ -32,6 +32,10 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtTypeArgumentList import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.renderer.render +import org.jetbrains.kotlin.idea.completion.lookups.TailTextProvider.getTailText +import org.jetbrains.kotlin.idea.completion.lookups.TailTextProvider.insertLambdaBraces +import org.jetbrains.kotlin.idea.completion.lookups.CompletionShortNamesRenderer.renderFunctionParameters +import org.jetbrains.kotlin.idea.completion.lookups.CompletionShortNamesRenderer.TYPE_RENDERING_OPTIONS internal class FunctionLookupElementFactory { fun KtAnalysisSession.createLookup( @@ -44,7 +48,8 @@ internal class FunctionLookupElementFactory { importStrategy = importStrategy, inputValueArguments = symbol.valueParameters.isNotEmpty(), insertEmptyLambda = insertLambdaBraces(symbol), - renderedFunctionParameters = with(CompletionShortNamesRenderer) { renderFunctionParameters(symbol) } + renderedFunctionParameters = renderFunctionParameters(symbol), + renderedReceiverType = symbol.receiverType?.type?.render(TYPE_RENDERING_OPTIONS) ) val insertionHandler = when (insertionStrategy) { @@ -65,14 +70,6 @@ internal class FunctionLookupElementFactory { } } - private fun KtAnalysisSession.getTailText(symbol: KtFunctionSymbol): String { - return if (insertLambdaBraces(symbol)) " {...}" else with(CompletionShortNamesRenderer) { renderFunctionParameters(symbol) } - } - - private fun KtAnalysisSession.insertLambdaBraces(symbol: KtFunctionSymbol): Boolean { - val singleParam = symbol.valueParameters.singleOrNull() - return singleParam != null && !singleParam.hasDefaultValue && singleParam.annotatedType.type is KtFunctionalType - } companion object { private val LOG = logger() @@ -88,8 +85,9 @@ private data class FunctionLookupObject( val inputValueArguments: Boolean, val insertEmptyLambda: Boolean, // for distinction between different overloads - private val renderedFunctionParameters: String -) : KotlinLookupObject + private val renderedFunctionParameters: String, + override val renderedReceiverType: String? +) : KotlinCallableLookupObject() private object FunctionInsertionHandler : QuotedNamesAwareInsertionHandler() { diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/factories/VariableLookupElementFactory.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/factories/VariableLookupElementFactory.kt index 33e78aea7b2..714b502a540 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/factories/VariableLookupElementFactory.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/lookups/factories/VariableLookupElementFactory.kt @@ -13,6 +13,7 @@ import com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.idea.completion.lookups.* import org.jetbrains.kotlin.idea.completion.lookups.CallableImportStrategy import org.jetbrains.kotlin.idea.completion.lookups.KotlinLookupObject +import org.jetbrains.kotlin.idea.completion.lookups.TailTextProvider.getTailText import org.jetbrains.kotlin.idea.completion.lookups.addCallableImportIfRequired import org.jetbrains.kotlin.idea.completion.lookups.detectImportStrategy import org.jetbrains.kotlin.idea.completion.lookups.shortenReferencesForFirCompletion @@ -32,11 +33,13 @@ internal class VariableLookupElementFactory { ): LookupElementBuilder { val lookupObject = VariableLookupObject( symbol.name, - importStrategy = importStrategy + importStrategy = importStrategy, + renderedReceiverType = symbol.receiverType?.type?.render(CompletionShortNamesRenderer.TYPE_RENDERING_OPTIONS), ) return LookupElementBuilder.create(lookupObject, symbol.name.asString()) .withTypeText(symbol.annotatedType.type.render(KtTypeRendererOptions.SHORT_NAMES)) + .withTailText(getTailText(symbol), true) .markIfSyntheticJavaProperty(symbol) .withInsertHandler(VariableInsertionHandler) .let { withSymbolInfo(symbol, it) } @@ -61,8 +64,9 @@ internal class VariableLookupElementFactory { */ private data class VariableLookupObject( override val shortName: Name, - val importStrategy: CallableImportStrategy -) : KotlinLookupObject + val importStrategy: CallableImportStrategy, + override val renderedReceiverType: String?, +) : KotlinCallableLookupObject() private object VariableInsertionHandler : InsertHandler {