FIR IDE: extract classifier completion separate completion provider

This commit is contained in:
Ilya Kirillov
2021-05-14 18:09:58 +02:00
committed by TeamCityServer
parent 1e5998e0ba
commit 3df075061c
3 changed files with 72 additions and 29 deletions
@@ -14,7 +14,9 @@ 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.FirClassifierCompletionContributor
import org.jetbrains.kotlin.idea.completion.contributors.FirCompletionContributorBase
import org.jetbrains.kotlin.idea.completion.contributors.FirContextCompletionContributorBase
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
@@ -127,13 +129,10 @@ internal fun interface CompletionVisibilityChecker {
*/
private class KotlinWithNameReferenceCompletionProvider(
basicContext: FirBasicCompletionContext,
private val indexHelper: IndexHelper
) : FirCompletionContributorBase(basicContext) {
indexHelper: IndexHelper
) : FirContextCompletionContributorBase(basicContext, indexHelper) {
private val typeNamesProvider = TypeNamesProvider(indexHelper)
private val scopeNameFilter: KtScopeNameFilter =
{ name -> !name.isSpecial && prefixMatcher.prefixMatches(name.identifier) }
private val shouldCompleteTopLevelCallablesFromIndex: Boolean
get() = prefixMatcher.prefix.isNotEmpty()
@@ -160,11 +159,13 @@ private class KotlinWithNameReferenceCompletionProvider(
}
when {
nameExpression.parent is KtUserType -> collectTypesCompletion(
scopesContext.scopes,
expectedType,
visibilityChecker
)
nameExpression.parent is KtUserType -> with(FirClassifierCompletionContributor(basicContext, indexHelper)) {
collectTypesCompletion(
scopesContext.scopes,
expectedType,
visibilityChecker
)
}
explicitReceiver != null -> {
collectDotCompletion(
scopesContext.scopes,
@@ -180,24 +181,6 @@ private class KotlinWithNameReferenceCompletionProvider(
}
private fun KtAnalysisSession.collectTypesCompletion(
implicitScopes: KtScope,
expectedType: KtType?,
visibilityChecker: CompletionVisibilityChecker,
) {
val classesFromScopes = implicitScopes
.getClassifierSymbols(scopeNameFilter)
.filter { visibilityChecker.isVisible(it) }
classesFromScopes.forEach { addSymbolToCompletion(expectedType, it) }
val kotlinClassesFromIndices = indexHelper.getKotlinClasses(scopeNameFilter, psiFilter = { it !is KtEnumEntry })
kotlinClassesFromIndices.asSequence()
.map { it.getSymbol() as KtClassifierSymbol }
.filter { visibilityChecker.isVisible(it) }
.forEach { addSymbolToCompletion(expectedType, it) }
}
private fun KtAnalysisSession.collectDotCompletion(
implicitScopes: KtCompositeScope,
explicitReceiver: KtExpression,
@@ -244,7 +227,9 @@ private class KotlinWithNameReferenceCompletionProvider(
collectTopLevelExtensionsFromIndices(implicitReceiversTypes, extensionChecker, visibilityChecker)
.forEach { addSymbolToCompletion(expectedType, it) }
collectTypesCompletion(implicitScopes, expectedType, visibilityChecker)
with(FirClassifierCompletionContributor(basicContext, indexHelper)) {
collectTypesCompletion(implicitScopes, expectedType, visibilityChecker)
}
}
private fun KtAnalysisSession.collectTopLevelExtensionsFromIndices(
@@ -0,0 +1,39 @@
/*
* 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 org.jetbrains.kotlin.idea.completion.CompletionVisibilityChecker
import org.jetbrains.kotlin.idea.completion.context.FirBasicCompletionContext
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScope
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassifierSymbol
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.psi.KtEnumEntry
internal class FirClassifierCompletionContributor(
basicContext: FirBasicCompletionContext,
indexHelper: IndexHelper
) : FirContextCompletionContributorBase(basicContext, indexHelper) {
fun KtAnalysisSession.collectTypesCompletion(
implicitScopes: KtScope,
expectedType: KtType?,
visibilityChecker: CompletionVisibilityChecker,
) {
val classesFromScopes = implicitScopes
.getClassifierSymbols(scopeNameFilter)
.filter { visibilityChecker.isVisible(it) }
classesFromScopes.forEach { addSymbolToCompletion(expectedType, it) }
val kotlinClassesFromIndices = indexHelper.getKotlinClasses(scopeNameFilter, psiFilter = { it !is KtEnumEntry })
kotlinClassesFromIndices.asSequence()
.map { it.getSymbol() as KtClassifierSymbol }
.filter { visibilityChecker.isVisible(it) }
.forEach { addSymbolToCompletion(expectedType, it) }
}
}
@@ -0,0 +1,19 @@
/*
* 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 org.jetbrains.kotlin.idea.completion.context.FirBasicCompletionContext
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeNameFilter
internal abstract class FirContextCompletionContributorBase(
basicContext: FirBasicCompletionContext,
protected val indexHelper: IndexHelper
) : FirCompletionContributorBase(basicContext) {
protected val scopeNameFilter: KtScopeNameFilter =
{ name -> !name.isSpecial && prefixMatcher.prefixMatches(name.identifier) }
}