FIR IDE: introduce base class for completion provider

This commit is contained in:
Ilya Kirillov
2021-05-06 15:40:26 +02:00
committed by TeamCityServer
parent 81c6f38f79
commit ca1fd185dc
3 changed files with 40 additions and 18 deletions
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.idea.completion.context.FirBasicCompletionContext
import org.jetbrains.kotlin.idea.completion.context.FirNameReferencePositionContext
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.weighers.Weighers
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
import org.jetbrains.kotlin.idea.fir.low.level.api.util.originalKtFile
@@ -48,7 +49,7 @@ private object KotlinFirCompletionProvider : CompletionProvider<CompletionParame
parameters.position.getModuleInfo().contentScope()
)
val basicContext = FirBasicCompletionContext.createFromParameters(parameters, result) ?: return
val basicContext = FirBasicCompletionContext.createFromParameters(parameters, resultSet) ?: return
recordOriginalFile(basicContext)
val positionContext = FirPositionCompletionContextDetector.detect(basicContext)
@@ -65,9 +66,9 @@ private object KotlinFirCompletionProvider : CompletionProvider<CompletionParame
FirPositionCompletionContextDetector.analyseInContext(basicContext, positionContext) {
when (positionContext) {
is FirNameReferencePositionContext -> with(
KotlinWithNameReferenceCompletionProvider(resultSet.prefixMatcher, indexHelper)
KotlinWithNameReferenceCompletionProvider(basicContext, indexHelper)
) {
addCompletions(basicContext, positionContext)
addCompletions(positionContext)
}
is FirUnknownPositionContext -> {
// TODO
@@ -135,9 +136,9 @@ internal fun interface CompletionVisibilityChecker {
* TODO refactor it, try to split into several classes, or decompose it into several classes.
*/
private class KotlinWithNameReferenceCompletionProvider(
private val prefixMatcher: PrefixMatcher,
basicContext: FirBasicCompletionContext,
private val indexHelper: IndexHelper
) {
): FirCompletionContributorBase(basicContext) {
private val lookupElementFactory = KotlinFirLookupElementFactory()
private val typeNamesProvider = TypeNamesProvider(indexHelper)
@@ -165,20 +166,19 @@ private class KotlinWithNameReferenceCompletionProvider(
}
fun KtAnalysisSession.addCompletions(
basicContext: FirBasicCompletionContext,
positionContext: FirNameReferencePositionContext
) = with(positionContext) {
val fileSymbol = basicContext.originalKtFile.getFileSymbol()
val fileSymbol = originalKtFile.getFileSymbol()
val expectedType = nameExpression.getExpectedType()
val scopesContext = basicContext.originalKtFile.getScopeContextForPosition(nameExpression)
val scopesContext = originalKtFile.getScopeContextForPosition(nameExpression)
val extensionChecker = ExtensionApplicabilityChecker {
it.checkExtensionIsSuitable(basicContext.originalKtFile, nameExpression, explicitReceiver)
it.checkExtensionIsSuitable(originalKtFile, nameExpression, explicitReceiver)
}
val visibilityChecker = CompletionVisibilityChecker {
basicContext.parameters.invocationCount > 1 || isVisible(
parameters.invocationCount > 1 || isVisible(
it,
fileSymbol,
positionContext.explicitReceiver,
@@ -188,14 +188,12 @@ private class KotlinWithNameReferenceCompletionProvider(
when {
nameExpression.parent is KtUserType -> collectTypesCompletion(
basicContext.result,
scopesContext.scopes,
expectedType,
visibilityChecker
)
explicitReceiver != null -> {
collectDotCompletion(
basicContext.result,
scopesContext.scopes,
explicitReceiver,
expectedType,
@@ -204,13 +202,12 @@ private class KotlinWithNameReferenceCompletionProvider(
)
}
else -> collectDefaultCompletion(basicContext.result, scopesContext, expectedType, extensionChecker, visibilityChecker)
else -> collectDefaultCompletion(scopesContext, expectedType, extensionChecker, visibilityChecker)
}
}
private fun KtAnalysisSession.collectTypesCompletion(
result: CompletionResultSet,
implicitScopes: KtScope,
expectedType: KtType?,
visibilityChecker: CompletionVisibilityChecker,
@@ -229,7 +226,6 @@ private class KotlinWithNameReferenceCompletionProvider(
}
private fun KtAnalysisSession.collectDotCompletion(
result: CompletionResultSet,
implicitScopes: KtCompositeScope,
explicitReceiver: KtExpression,
expectedType: KtType?,
@@ -250,7 +246,6 @@ private class KotlinWithNameReferenceCompletionProvider(
}
private fun KtAnalysisSession.collectDefaultCompletion(
result: CompletionResultSet,
implicitScopesContext: KtScopeContext,
expectedType: KtType?,
extensionChecker: ExtensionApplicabilityChecker,
@@ -275,7 +270,7 @@ private class KotlinWithNameReferenceCompletionProvider(
collectTopLevelExtensionsFromIndices(implicitReceiversTypes, extensionChecker, visibilityChecker)
.forEach { addSymbolToCompletion(result, expectedType, it) }
collectTypesCompletion(result, implicitScopes, expectedType, visibilityChecker)
collectTypesCompletion(implicitScopes, expectedType, visibilityChecker)
}
private fun KtAnalysisSession.collectTopLevelExtensionsFromIndices(
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.completion.context
import com.intellij.codeInsight.completion.CompletionParameters
import com.intellij.codeInsight.completion.CompletionResultSet
import com.intellij.codeInsight.completion.PrefixMatcher
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.platform.TargetPlatform
@@ -15,6 +16,7 @@ import org.jetbrains.kotlin.psi.KtFile
internal class FirBasicCompletionContext(
val parameters: CompletionParameters,
val result: CompletionResultSet,
val prefixMatcher: PrefixMatcher,
val originalKtFile: KtFile,
val fakeKtFile: KtFile,
val project: Project,
@@ -22,11 +24,12 @@ internal class FirBasicCompletionContext(
) {
companion object {
fun createFromParameters(parameters: CompletionParameters, result: CompletionResultSet): FirBasicCompletionContext? {
val prefixMatcher = result.prefixMatcher
val originalKtFile = parameters.originalFile as? KtFile ?: return null
val fakeKtFile = parameters.position.containingFile as? KtFile ?: return null
val targetPlatform = TargetPlatformDetector.getPlatform(originalKtFile)
val project = originalKtFile.project
return FirBasicCompletionContext(parameters, result, originalKtFile, fakeKtFile, project, targetPlatform)
return FirBasicCompletionContext(parameters, result, prefixMatcher, originalKtFile, fakeKtFile, project, targetPlatform)
}
}
}
@@ -0,0 +1,24 @@
/*
* 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.codeInsight.completion.CompletionParameters
import com.intellij.codeInsight.completion.CompletionResultSet
import com.intellij.codeInsight.completion.PrefixMatcher
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.completion.context.FirBasicCompletionContext
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.psi.KtFile
internal abstract class FirCompletionContributorBase(protected val basicContext: FirBasicCompletionContext) {
protected val prefixMatcher: PrefixMatcher get() = basicContext.prefixMatcher
protected val parameters: CompletionParameters get() = basicContext.parameters
protected val result: CompletionResultSet get() = basicContext.result
protected val originalKtFile: KtFile get() = basicContext.originalKtFile
protected val fakeKtFile: KtFile get() = basicContext.fakeKtFile
protected val project: Project get() = basicContext.project
protected val targetPlatform: TargetPlatform get() = basicContext.targetPlatform
}