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.
|
* TODO refactor it, try to split into several classes, or decompose it into several classes.
|
||||||
*/
|
*/
|
||||||
private class KotlinCommonCompletionProvider(
|
private class KotlinCommonCompletionProvider(
|
||||||
prefixMatcher: PrefixMatcher,
|
private val prefixMatcher: PrefixMatcher,
|
||||||
private val indexHelper: IndexHelper
|
private val indexHelper: IndexHelper
|
||||||
) {
|
) {
|
||||||
private val lookupElementFactory = KotlinFirLookupElementFactory()
|
private val lookupElementFactory = KotlinFirLookupElementFactory()
|
||||||
@@ -93,6 +93,9 @@ private class KotlinCommonCompletionProvider(
|
|||||||
private val scopeNameFilter: KtScopeNameFilter =
|
private val scopeNameFilter: KtScopeNameFilter =
|
||||||
{ name -> !name.isSpecial && prefixMatcher.prefixMatches(name.identifier) }
|
{ 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) {
|
private fun KtAnalysisSession.addSymbolToCompletion(completionResultSet: CompletionResultSet, expectedType: KtType?, symbol: KtSymbol) {
|
||||||
if (symbol !is KtNamedSymbol) return
|
if (symbol !is KtNamedSymbol) return
|
||||||
with(lookupElementFactory) {
|
with(lookupElementFactory) {
|
||||||
@@ -199,6 +202,14 @@ private class KotlinCommonCompletionProvider(
|
|||||||
availableNonExtensions.forEach { addSymbolToCompletion(result, expectedType, it) }
|
availableNonExtensions.forEach { addSymbolToCompletion(result, expectedType, it) }
|
||||||
extensionsWhichCanBeCalled.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)
|
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.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.psi.stubs.StringStubIndexExtension
|
||||||
import com.intellij.psi.stubs.StubIndex
|
import com.intellij.psi.stubs.StubIndex
|
||||||
import com.intellij.psi.stubs.StubIndexKey
|
import com.intellij.psi.stubs.StubIndexKey
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
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.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Move to another module
|
* Move to another module
|
||||||
@@ -86,6 +84,20 @@ public class IndexHelper(val project: Project, private val scope: GlobalSearchSc
|
|||||||
.toList()
|
.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 {
|
companion object {
|
||||||
private fun CallableId.asStringForIndexes(): String =
|
private fun CallableId.asStringForIndexes(): String =
|
||||||
(if (packageName.isRoot) callableName.asString() else toString()).replace('/', '.')
|
(if (packageName.isRoot) callableName.asString() else toString()).replace('/', '.')
|
||||||
|
|||||||
Reference in New Issue
Block a user