From 879cf3b0498561a79fdfbe4057a114fd02a53247 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Wed, 16 Sep 2020 13:05:43 +0300 Subject: [PATCH] FIR IDE: do not fail whole completion on exception in lookup element creation --- .../KotlinFirCompletionContributor.kt | 2 +- .../KotlinFirLookupElementFactory.kt | 27 ++++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt index ac2e8b8cff7..868e12de9f0 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirCompletionContributor.kt @@ -68,7 +68,7 @@ private class KotlinAvailableScopesCompletionProvider(prefixMatcher: PrefixMatch private fun CompletionResultSet.addSymbolToCompletion(symbol: KtSymbol) { if (symbol !is KtNamedSymbol) return - addElement(lookupElementFactory.createLookupElement(symbol)) + lookupElementFactory.createLookupElement(symbol)?.let(::addElement) } @OptIn(InvalidWayOfUsingAnalysisSession::class) diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirLookupElementFactory.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirLookupElementFactory.kt index f27a2f0cc10..2f44fe463a2 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirLookupElementFactory.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/completion/KotlinFirLookupElementFactory.kt @@ -11,7 +11,10 @@ import com.intellij.codeInsight.completion.InsertionContext import com.intellij.codeInsight.lookup.Lookup import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElementBuilder +import com.intellij.openapi.diagnostic.ControlFlowException +import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.editor.Document +import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.frontend.api.symbols.* @@ -30,14 +33,14 @@ internal class KotlinFirLookupElementFactory { private val functionLookupElementFactory = FunctionLookupElementFactory() private val typeParameterLookupElementFactory = TypeParameterLookupElementFactory() - fun createLookupElement(symbol: KtNamedSymbol): LookupElement { + fun createLookupElement(symbol: KtNamedSymbol): LookupElement? { val elementBuilder = when (symbol) { is KtFunctionSymbol -> functionLookupElementFactory.createLookup(symbol) is KtVariableLikeSymbol -> variableLookupElementFactory.createLookup(symbol) is KtClassLikeSymbol -> classLookupElementFactory.createLookup(symbol) is KtTypeParameterSymbol -> typeParameterLookupElementFactory.createLookup(symbol) else -> throw IllegalArgumentException("Cannot create a lookup element for $symbol") - } + } ?: return null return elementBuilder .withPsiElement(symbol.psi) // TODO check if it is a heavy operation and should be postponed @@ -75,11 +78,17 @@ private class VariableLookupElementFactory { } private class FunctionLookupElementFactory { - fun createLookup(symbol: KtFunctionSymbol): LookupElementBuilder { - return LookupElementBuilder.create(UniqueLookupObject(), symbol.name.asString()) - .withTailText(getTailText(symbol), true) - .withTypeText(ShortNamesRenderer.renderType(symbol.type)) - .withInsertHandler(createInsertHandler(symbol)) + fun createLookup(symbol: KtFunctionSymbol): LookupElementBuilder? { + return try { + LookupElementBuilder.create(UniqueLookupObject(), symbol.name.asString()) + .withTailText(getTailText(symbol), true) + .withTypeText(ShortNamesRenderer.renderType(symbol.type)) + .withInsertHandler(createInsertHandler(symbol)) + } catch (e: Throwable) { + if (e is ControlFlowException) throw e + LOG.error(e) + null + } } private fun getTailText(symbol: KtFunctionSymbol): String { @@ -98,6 +107,10 @@ private class FunctionLookupElementFactory { insertEmptyLambda = insertLambdaBraces(symbol) ) } + + companion object { + private val LOG = logger() + } } /**