FIR IDE: Add completion for top level functions and properties
This commit is contained in:
+12
-1
@@ -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)
|
||||
}
|
||||
}
|
||||
+16
-4
@@ -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('/', '.')
|
||||
|
||||
Reference in New Issue
Block a user