diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/completion/HighLevelApiLookupElementFactory.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/completion/HighLevelApiLookupElementFactory.kt new file mode 100644 index 00000000000..440013444aa --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/completion/HighLevelApiLookupElementFactory.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2010-2020 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 + +import com.intellij.codeInsight.lookup.LookupElement +import com.intellij.codeInsight.lookup.LookupElementBuilder +import org.jetbrains.kotlin.idea.frontend.api.symbols.* +import org.jetbrains.kotlin.idea.frontend.api.types.KtDenotableType +import org.jetbrains.kotlin.idea.frontend.api.types.KtType + +internal class HighLevelApiLookupElementFactory { + private val classLookupElementFactory = ClassLookupElementFactory() + private val variableLookupElementFactory = VariableLookupElementFactory() + private val functionLookupElementFactory = FunctionLookupElementFactory() + + fun createLookupElement(symbol: KtNamedSymbol): LookupElement { + val elementBuilder = when (symbol) { + is KtFunctionSymbol -> functionLookupElementFactory.createLookup(symbol) + is KtVariableLikeSymbol -> variableLookupElementFactory.createLookup(symbol) + is KtClassLikeSymbol -> classLookupElementFactory.createLookup(symbol) + else -> throw IllegalArgumentException("Cannot create a lookup element for $symbol") + } + + return elementBuilder.withIcon(KotlinSymbolIconProvider.getIconFor(symbol)) + } +} + +private class ClassLookupElementFactory { + fun createLookup(symbol: KtClassLikeSymbol): LookupElementBuilder { + return LookupElementBuilder.create(symbol.name.asString()) + } +} + +private class VariableLookupElementFactory { + fun createLookup(symbol: KtVariableLikeSymbol): LookupElementBuilder { + return LookupElementBuilder.create(symbol.name.asString()) + .withTypeText(ShortNamesRenderer.renderType(symbol.type)) + } +} + +private class FunctionLookupElementFactory { + fun createLookup(symbol: KtFunctionSymbol): LookupElementBuilder { + return LookupElementBuilder.create(symbol.name.asString()) + .appendTailText(ShortNamesRenderer.renderFunctionParameters(symbol), true) + .withTypeText(ShortNamesRenderer.renderType(symbol.type)) + } +} + + +private object ShortNamesRenderer { + fun renderFunctionParameters(function: KtFunctionSymbol): String = + function.valueParameters.joinToString(", ", "(", ")") { renderFunctionParameter(it) } + + fun renderType(ktType: KtType): String = (ktType as? KtDenotableType)?.asString() ?: "" + + private fun renderFunctionParameter(param: KtFunctionParameterSymbol) = "${param.name.asString()}: ${renderType(param.type)}" +} diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt index e1ed35c8f01..b42980a0e3a 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.idea.completion import com.intellij.codeInsight.completion.* -import com.intellij.codeInsight.lookup.LookupElementBuilder import com.intellij.patterns.PlatformPatterns import com.intellij.patterns.PsiJavaPatterns import com.intellij.util.ProcessingContext @@ -27,6 +26,8 @@ class KotlinFirCompletionContributor : CompletionContributor() { } private object KotlinHighLevelApiContributor : CompletionProvider() { + private val lookupElementFactory = HighLevelApiLookupElementFactory() + override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) { if (shouldSuppressCompletion(parameters, result.prefixMatcher)) return @@ -48,7 +49,7 @@ private object KotlinHighLevelApiContributor : CompletionProvider { + if (isAbstract) KotlinIcons.ABSTRACT_EXTENSION_FUNCTION else KotlinIcons.EXTENSION_FUNCTION + } + symbol.symbolKind == KtSymbolKind.MEMBER -> { + if (isAbstract) PlatformIcons.ABSTRACT_METHOD_ICON else PlatformIcons.METHOD_ICON + } + else -> KotlinIcons.FUNCTION + } + } + + if (symbol is KtClassOrObjectSymbol) { + val isAbstract = symbol.modality == KtCommonSymbolModality.ABSTRACT + + return when (symbol.classKind) { + KtClassKind.CLASS -> if (isAbstract) KotlinIcons.CLASS else KotlinIcons.ABSTRACT_CLASS + KtClassKind.ENUM_CLASS, KtClassKind.ENUM_ENTRY -> KotlinIcons.ENUM + KtClassKind.ANNOTATION_CLASS -> KotlinIcons.ANNOTATION + KtClassKind.OBJECT, KtClassKind.COMPANION_OBJECT -> KotlinIcons.OBJECT + KtClassKind.INTERFACE -> KotlinIcons.INTERFACE + } + } + + if (symbol is KtParameterSymbol) return KotlinIcons.PARAMETER + + if (symbol is KtLocalVariableSymbol) return if (symbol.isVal) KotlinIcons.VAL else KotlinIcons.VAR + + if (symbol is KtPropertySymbol) return if (symbol.isVal) KotlinIcons.FIELD_VAL else KotlinIcons.FIELD_VAR + + if (symbol is KtTypeParameterSymbol) return PlatformIcons.CLASS_ICON + + if (symbol is KtTypeAliasSymbol) return KotlinIcons.TYPE_ALIAS + + return null + } +} \ No newline at end of file