FIR IDE: Add completion for top level functions and properties

This commit is contained in:
Roman Golyshev
2021-02-19 18:52:31 +03:00
parent 62389bad0b
commit d6d3d3a6ad
2 changed files with 28 additions and 5 deletions
@@ -85,7 +85,7 @@ private object KotlinFirCompletionProvider : CompletionProvider<CompletionParame
* TODO refactor it, try to split into several classes, or decompose it into several classes.
*/
private class KotlinCommonCompletionProvider(
prefixMatcher: PrefixMatcher,
private val prefixMatcher: PrefixMatcher,
private val indexHelper: IndexHelper
) {
private val lookupElementFactory = KotlinFirLookupElementFactory()
@@ -93,6 +93,9 @@ private class KotlinCommonCompletionProvider(
private val scopeNameFilter: KtScopeNameFilter =
{ name -> !name.isSpecial && prefixMatcher.prefixMatches(name.identifier) }
private val shouldCompleteTopLevelCallablesFromIndex: Boolean
get() = prefixMatcher.prefix.isNotEmpty()
private fun KtAnalysisSession.addSymbolToCompletion(completionResultSet: CompletionResultSet, expectedType: KtType?, symbol: KtSymbol) {
if (symbol !is KtNamedSymbol) return
with(lookupElementFactory) {
@@ -199,6 +202,14 @@ private class KotlinCommonCompletionProvider(
availableNonExtensions.forEach { addSymbolToCompletion(result, expectedType, it) }
extensionsWhichCanBeCalled.forEach { addSymbolToCompletion(result, expectedType, it) }
if (shouldCompleteTopLevelCallablesFromIndex) {
val topLevelCallables = indexHelper.getTopLevelCallables(scopeNameFilter)
topLevelCallables.asSequence()
.map { it.getSymbol() }
.forEach { addSymbolToCompletion(result, expectedType, it) }
}
collectTypesCompletion(result, implicitScopes, expectedType)
}
}
@@ -9,6 +9,7 @@ import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.StringStubIndexExtension
import com.intellij.psi.stubs.StubIndex
import com.intellij.psi.stubs.StubIndexKey
import org.jetbrains.kotlin.name.CallableId
@@ -16,10 +17,7 @@ import org.jetbrains.kotlin.idea.stubindex.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.*
/*
* Move to another module
@@ -86,6 +84,20 @@ public class IndexHelper(val project: Project, private val scope: GlobalSearchSc
.toList()
}
fun getTopLevelCallables(nameFilter: (Name) -> Boolean): Collection<KtCallableDeclaration> {
fun sequenceOfElements(index: StringStubIndexExtension<out KtCallableDeclaration>): Sequence<KtCallableDeclaration> =
index.getAllKeys(project).asSequence()
.onEach { ProgressManager.checkCanceled() }
.filter { fqName -> nameFilter(getShortName(fqName)) }
.flatMap { fqName -> index[fqName, project, scope] }
.filter { it.receiverTypeReference == null }
val functions = sequenceOfElements(KotlinTopLevelFunctionFqnNameIndex.getInstance())
val properties = sequenceOfElements(KotlinTopLevelPropertyFqnNameIndex.getInstance())
return (functions + properties).toList()
}
companion object {
private fun CallableId.asStringForIndexes(): String =
(if (packageName.isRoot) callableName.asString() else toString()).replace('/', '.')