FIR IDE: make FirKeywordCompletion to be a completion contributor

This commit is contained in:
Ilya Kirillov
2021-05-06 16:57:09 +02:00
committed by TeamCityServer
parent ca1fd185dc
commit 8cfa85df6b
3 changed files with 73 additions and 70 deletions
@@ -1,51 +0,0 @@
/*
* 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
import com.intellij.codeInsight.completion.CompletionParameters
import com.intellij.codeInsight.completion.CompletionResultSet
import com.intellij.codeInsight.completion.PrefixMatcher
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.psi.KtExpressionWithLabel
import org.jetbrains.kotlin.psi.KtLabelReferenceExpression
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
object FirKeywordCompletion {
private val keywordCompletion = KeywordCompletion(object : KeywordCompletion.LanguageVersionSettingProvider {
override fun getLanguageVersionSetting(element: PsiElement) = LanguageVersionSettingsImpl.DEFAULT // TODO
override fun getLanguageVersionSetting(module: Module) = LanguageVersionSettingsImpl.DEFAULT // TODO
})
fun completeKeywords(
result: CompletionResultSet,
parameters: CompletionParameters,
position: PsiElement,
prefixMatcher: PrefixMatcher,
project: Project,
isJvmModule: Boolean
) {
val reference = (position.parent as? KtSimpleNameExpression)?.mainReference
val expression = if (reference != null) { // logic is copy-n-pasted from CompletionSession.expression
if (reference.expression is KtLabelReferenceExpression) {
reference.expression.parent.parent as? KtExpressionWithLabel
} else {
reference.expression
}
} else null
keywordCompletion.complete(expression ?: position, prefixMatcher, isJvmModule) { lookupElement ->
val keyword = lookupElement.lookupString
val completionKeywordHandler = DefaultCompletionKeywordHandlers.defaultHandlers.getHandlerForKeyword(keyword)
val lookups = completionKeywordHandler
?.createLookups(parameters, expression, lookupElement, project)
?: listOf(lookupElement)
result.addAllElements(lookups)
}
}
}
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.idea.completion.context.FirNameReferencePositionCont
import org.jetbrains.kotlin.idea.completion.context.FirPositionCompletionContextDetector
import org.jetbrains.kotlin.idea.completion.context.FirUnknownPositionContext
import org.jetbrains.kotlin.idea.completion.contributors.FirCompletionContributorBase
import org.jetbrains.kotlin.idea.completion.contributors.FirKeywordCompletionContributor
import org.jetbrains.kotlin.idea.completion.weighers.Weighers
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
import org.jetbrains.kotlin.idea.fir.low.level.api.util.originalKtFile
@@ -53,25 +54,23 @@ private object KotlinFirCompletionProvider : CompletionProvider<CompletionParame
recordOriginalFile(basicContext)
val positionContext = FirPositionCompletionContextDetector.detect(basicContext)
FirKeywordCompletion.completeKeywords(
result,
parameters,
parameters.position,
resultSet.prefixMatcher,
basicContext.project,
isJvmModule = basicContext.targetPlatform.isJvm()
)
val keywordContributor = FirKeywordCompletionContributor(basicContext)
FirPositionCompletionContextDetector.analyseInContext(basicContext, positionContext) {
when (positionContext) {
is FirNameReferencePositionContext -> with(
KotlinWithNameReferenceCompletionProvider(basicContext, indexHelper)
) {
addCompletions(positionContext)
}
is FirUnknownPositionContext -> {
// TODO
if (positionContext is FirUnknownPositionContext) {
// TODO unify when LL API will be able to handle more context for completion
keywordContributor.completeKeywordsWithoutAnalysisSessionContext(positionContext.position, expression = null)
} else {
FirPositionCompletionContextDetector.analyseInContext(basicContext, positionContext) {
with(keywordContributor) { completeKeywords(positionContext) }
when (positionContext) {
is FirNameReferencePositionContext -> with(
KotlinWithNameReferenceCompletionProvider(basicContext, indexHelper)
) {
addCompletions(positionContext)
}
is FirUnknownPositionContext -> {
// TODO remove when hack when LL API will be able to handle more context for completion
}
}
}
}
@@ -138,7 +137,7 @@ internal fun interface CompletionVisibilityChecker {
private class KotlinWithNameReferenceCompletionProvider(
basicContext: FirBasicCompletionContext,
private val indexHelper: IndexHelper
): FirCompletionContributorBase(basicContext) {
) : FirCompletionContributorBase(basicContext) {
private val lookupElementFactory = KotlinFirLookupElementFactory()
private val typeNamesProvider = TypeNamesProvider(indexHelper)
@@ -0,0 +1,55 @@
/*
* 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.contributors
import com.intellij.openapi.module.Module
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.idea.completion.DefaultCompletionKeywordHandlers
import org.jetbrains.kotlin.idea.completion.KeywordCompletion
import org.jetbrains.kotlin.idea.completion.context.FirBasicCompletionContext
import org.jetbrains.kotlin.idea.completion.context.FirNameReferencePositionContext
import org.jetbrains.kotlin.idea.completion.context.FirPositionCompletionContext
import org.jetbrains.kotlin.idea.completion.context.FirUnknownPositionContext
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.platform.jvm.isJvm
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtExpressionWithLabel
import org.jetbrains.kotlin.psi.KtLabelReferenceExpression
internal class FirKeywordCompletionContributor(basicContext: FirBasicCompletionContext) : FirCompletionContributorBase(basicContext) {
private val keywordCompletion = KeywordCompletion(object : KeywordCompletion.LanguageVersionSettingProvider {
override fun getLanguageVersionSetting(element: PsiElement) = LanguageVersionSettingsImpl.DEFAULT // TODO
override fun getLanguageVersionSetting(module: Module) = LanguageVersionSettingsImpl.DEFAULT // TODO
})
fun KtAnalysisSession.completeKeywords(
positionContext: FirPositionCompletionContext
) {
val expression = when (positionContext) {
is FirNameReferencePositionContext -> {
val reference = positionContext.reference
when (reference.expression) {
is KtLabelReferenceExpression -> reference.expression.parent.parent as? KtExpressionWithLabel
else -> reference.expression
}
}
is FirUnknownPositionContext -> null
}
completeKeywordsWithoutAnalysisSessionContext(expression ?: positionContext.position, expression)
}
fun completeKeywordsWithoutAnalysisSessionContext(position: PsiElement, expression: KtExpression?) {
keywordCompletion.complete(position, prefixMatcher, targetPlatform.isJvm()) { lookupElement ->
val keyword = lookupElement.lookupString
val completionKeywordHandler = DefaultCompletionKeywordHandlers.defaultHandlers.getHandlerForKeyword(keyword)
val lookups = completionKeywordHandler
?.createLookups(parameters, expression, lookupElement, project)
?: listOf(lookupElement)
result.addAllElements(lookups)
}
}
}