Optimization to not fetch objects in separate pass
This commit is contained in:
@@ -42,6 +42,8 @@ public class KotlinIndicesHelper(private val project: Project,
|
||||
private val resolveSession: ResolveSessionForBodies,
|
||||
private val scope: GlobalSearchScope,
|
||||
private val visibilityFilter: (DeclarationDescriptor) -> Boolean) {
|
||||
private val moduleDescriptor = resolveSession.getModuleDescriptor()
|
||||
|
||||
public fun getTopLevelObjects(nameFilter: (String) -> Boolean): Collection<ClassDescriptor> {
|
||||
val allObjectNames = JetTopLevelObjectShortNameIndex.getInstance().getAllKeys(project).stream() +
|
||||
JetFromJavaDescriptorHelper.getPossiblePackageDeclarationsNames(project, scope).stream()
|
||||
@@ -57,13 +59,13 @@ public class KotlinIndicesHelper(private val project: Project,
|
||||
val topObjects = JetTopLevelObjectShortNameIndex.getInstance().get(name, project, scope)
|
||||
for (objectDeclaration in topObjects) {
|
||||
val fqName = objectDeclaration.getFqName() ?: error("Local object declaration in JetTopLevelShortObjectNameIndex:${objectDeclaration.getText()}")
|
||||
result.addAll(ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(resolveSession.getModuleDescriptor(), fqName, ResolveSessionUtils.SINGLETON_FILTER))
|
||||
result.addAll(ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(moduleDescriptor, fqName, ResolveSessionUtils.SINGLETON_FILTER))
|
||||
}
|
||||
|
||||
for (psiClass in JetFromJavaDescriptorHelper.getCompiledClassesForTopLevelObjects(project, scope)) {
|
||||
val qualifiedName = psiClass.getQualifiedName()
|
||||
if (qualifiedName != null) {
|
||||
result.addAll(ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(resolveSession.getModuleDescriptor(), FqName(qualifiedName), ResolveSessionUtils.SINGLETON_FILTER))
|
||||
result.addAll(ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(moduleDescriptor, FqName(qualifiedName), ResolveSessionUtils.SINGLETON_FILTER))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +101,7 @@ public class KotlinIndicesHelper(private val project: Project,
|
||||
.toSet()
|
||||
|
||||
for (affectedPackage in affectedPackages) {
|
||||
val packageDescriptor = resolveSession.getModuleDescriptor().getPackage(affectedPackage)
|
||||
val packageDescriptor = moduleDescriptor.getPackage(affectedPackage)
|
||||
?: error("There's a function in stub index with invalid package: $affectedPackage")
|
||||
addAll(packageDescriptor.getMemberScope().getFunctions(identifier))
|
||||
}
|
||||
@@ -115,7 +117,7 @@ public class KotlinIndicesHelper(private val project: Project,
|
||||
.toSet()
|
||||
|
||||
for (affectedPackage in affectedPackages) {
|
||||
val packageDescriptor = resolveSession.getModuleDescriptor().getPackage(affectedPackage)
|
||||
val packageDescriptor = moduleDescriptor.getPackage(affectedPackage)
|
||||
?: error("There's a property in stub index with invalid package: $affectedPackage")
|
||||
addAll(packageDescriptor.getMemberScope().getProperties(identifier))
|
||||
}
|
||||
@@ -153,7 +155,7 @@ public class KotlinIndicesHelper(private val project: Project,
|
||||
val receiverValue = ExpressionReceiver(receiverExpression, expressionType)
|
||||
|
||||
return matchingFqNames.flatMap {
|
||||
findSuitableExtensions(it, receiverValue, dataFlowInfo, isInfixCall, resolutionScope, resolveSession.getModuleDescriptor(), bindingContext)
|
||||
findSuitableExtensions(it, receiverValue, dataFlowInfo, isInfixCall, resolutionScope, moduleDescriptor, bindingContext)
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -162,7 +164,7 @@ public class KotlinIndicesHelper(private val project: Project,
|
||||
val result = HashSet<CallableDescriptor>()
|
||||
for (receiver in resolutionScope.getImplicitReceiversHierarchy()) {
|
||||
matchingFqNames.flatMapTo(result) {
|
||||
findSuitableExtensions(it, receiver.getValue(), dataFlowInfo, false, resolutionScope, resolveSession.getModuleDescriptor(), bindingContext)
|
||||
findSuitableExtensions(it, receiver.getValue(), dataFlowInfo, false, resolutionScope, moduleDescriptor, bindingContext)
|
||||
}
|
||||
}
|
||||
return result
|
||||
@@ -190,29 +192,30 @@ public class KotlinIndicesHelper(private val project: Project,
|
||||
ExpressionTypingUtils.checkIsExtensionCallable(receiverValue, it, isInfixCall, bindingContext, dataFlowInfo) }
|
||||
}
|
||||
|
||||
public fun getClassDescriptors(nameFilter: (String) -> Boolean): Collection<ClassDescriptor> {
|
||||
public fun getClassDescriptors(nameFilter: (String) -> Boolean, kindFilter: (ClassKind) -> Boolean): Collection<ClassDescriptor> {
|
||||
return JetFullClassNameIndex.getInstance().getAllKeys(project).stream()
|
||||
.map { FqName(it) }
|
||||
.filter { nameFilter(it.shortName().asString()) }
|
||||
.toList()
|
||||
.flatMap { getClassDescriptorsByFQName(it) }
|
||||
.flatMap { getClassDescriptorsByFQName(it, kindFilter) }
|
||||
}
|
||||
|
||||
private fun getClassDescriptorsByFQName(classFQName: FqName): Collection<ClassDescriptor> {
|
||||
val jetClassOrObjects = JetFullClassNameIndex.getInstance().get(classFQName.asString(), project, scope)
|
||||
private fun getClassDescriptorsByFQName(classFQName: FqName, kindFilter: (ClassKind) -> Boolean): Collection<ClassDescriptor> {
|
||||
val declarations = JetFullClassNameIndex.getInstance()[classFQName.asString(), project, scope]
|
||||
|
||||
if (jetClassOrObjects.isEmpty()) {
|
||||
if (declarations.isEmpty()) {
|
||||
// This fqn is absent in caches, dead or not in scope
|
||||
return listOf()
|
||||
}
|
||||
|
||||
// Note: Can't search with psi element as analyzer could be built over temp files
|
||||
return ResolveSessionUtils.getClassDescriptorsByFqName(resolveSession.getModuleDescriptor(), classFQName).filter(visibilityFilter)
|
||||
return ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(moduleDescriptor, classFQName) { kindFilter(it.getKind()) }
|
||||
.filter(visibilityFilter)
|
||||
}
|
||||
|
||||
private fun findTopLevelCallables(fqName: FqName, context: JetExpression, jetScope: JetScope): Collection<CallableDescriptor> {
|
||||
val importDirective = JetPsiFactory(context.getProject()).createImportDirective(ImportPath(fqName, false))
|
||||
val allDescriptors = analyzeImportReference(importDirective, jetScope, BindingTraceContext(), resolveSession.getModuleDescriptor())
|
||||
val allDescriptors = analyzeImportReference(importDirective, jetScope, BindingTraceContext(), moduleDescriptor)
|
||||
return allDescriptors.filterIsInstance(javaClass<CallableDescriptor>()).filter { it.getExtensionReceiverParameter() == null }
|
||||
}
|
||||
|
||||
|
||||
+20
-10
@@ -31,18 +31,20 @@ import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
|
||||
import org.jetbrains.jet.plugin.caches.KotlinIndicesHelper
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
|
||||
class TypesCompletion(val parameters: CompletionParameters,
|
||||
val resolveSession: ResolveSessionForBodies,
|
||||
val prefixMatcher: PrefixMatcher,
|
||||
val visibilityFilter: (DeclarationDescriptor) -> Boolean) {
|
||||
fun addAllTypes(result: LookupElementsCollector) {
|
||||
result.addDescriptorElements(KotlinBuiltIns.getInstance().getNonPhysicalClasses().filter { prefixMatcher.prefixMatches(it.getName().asString()) },
|
||||
suppressAutoInsertion = true)
|
||||
class AllClassesCompletion(val parameters: CompletionParameters,
|
||||
val resolveSession: ResolveSessionForBodies,
|
||||
val prefixMatcher: PrefixMatcher,
|
||||
val kindFilter: (ClassKind) -> Boolean,
|
||||
val visibilityFilter: (DeclarationDescriptor) -> Boolean) {
|
||||
fun collect(result: LookupElementsCollector) {
|
||||
val builtIns = KotlinBuiltIns.getInstance().getNonPhysicalClasses().filter { kindFilter(it.getKind()) && prefixMatcher.prefixMatches(it.getName().asString()) }
|
||||
result.addDescriptorElements(builtIns, suppressAutoInsertion = true)
|
||||
|
||||
val file = parameters.getOriginalFile()
|
||||
val project = file.getProject()
|
||||
val searchScope = file.getResolveScope()
|
||||
result.addDescriptorElements(KotlinIndicesHelper(project, resolveSession, searchScope, visibilityFilter).getClassDescriptors { prefixMatcher.prefixMatches(it) },
|
||||
val helper = KotlinIndicesHelper(project, resolveSession, searchScope, visibilityFilter)
|
||||
result.addDescriptorElements(helper.getClassDescriptors({ prefixMatcher.prefixMatches(it) }, kindFilter),
|
||||
suppressAutoInsertion = true)
|
||||
|
||||
if (!ProjectStructureUtil.isJsKotlinModule(file as JetFile)) {
|
||||
@@ -60,14 +62,22 @@ class TypesCompletion(val parameters: CompletionParameters,
|
||||
addLookupElementForCompiledKotlinClass(psiClass, collector)
|
||||
}
|
||||
else if (!JavaResolverUtils.isCompiledKotlinPackageClass(psiClass)) {
|
||||
collector.addElementWithAutoInsertionSuppressed(KotlinLookupElementFactory.createLookupElementForJavaClass(psiClass))
|
||||
val kind = when {
|
||||
psiClass.isAnnotationType() -> ClassKind.ANNOTATION_CLASS
|
||||
psiClass.isInterface() -> ClassKind.TRAIT
|
||||
psiClass.isEnum() -> ClassKind.ENUM_CLASS
|
||||
else -> ClassKind.CLASS
|
||||
}
|
||||
if (kindFilter(kind)) {
|
||||
collector.addElementWithAutoInsertionSuppressed(KotlinLookupElementFactory.createLookupElementForJavaClass(psiClass))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun addLookupElementForCompiledKotlinClass(aClass: PsiClass, collector: LookupElementsCollector) {
|
||||
if (JetFromJavaDescriptorHelper.getCompiledClassKind(aClass) != ClassKind.CLASS_OBJECT) {
|
||||
if (kindFilter(JetFromJavaDescriptorHelper.getCompiledClassKind(aClass))) {
|
||||
val qualifiedName = aClass.getQualifiedName()
|
||||
if (qualifiedName != null) {
|
||||
val descriptors = ResolveSessionUtils.getClassDescriptorsByFqName(resolveSession.getModuleDescriptor(), FqName(qualifiedName)).filter(visibilityFilter)
|
||||
@@ -110,17 +110,20 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
return configuration.completeNonImportedDeclarations || prefixMatcher.getPrefix().length >= 3
|
||||
}
|
||||
|
||||
protected fun getKotlinTopLevelDeclarations(): Collection<DeclarationDescriptor> {
|
||||
val filter = { (name: String) -> prefixMatcher.prefixMatches(name) }
|
||||
return indicesHelper.getTopLevelCallables(filter, jetReference!!.expression) + indicesHelper.getTopLevelObjects(filter)
|
||||
protected fun getKotlinTopLevelCallables(): Collection<DeclarationDescriptor> {
|
||||
return indicesHelper.getTopLevelCallables({ prefixMatcher.prefixMatches(it) }, jetReference!!.expression)
|
||||
}
|
||||
|
||||
protected fun getKotlinTopLevelObjects(): Collection<DeclarationDescriptor> {
|
||||
return indicesHelper.getTopLevelObjects({ prefixMatcher.prefixMatches(it) })
|
||||
}
|
||||
|
||||
protected fun getKotlinExtensions(): Collection<CallableDescriptor> {
|
||||
return indicesHelper.getCallableExtensions({ prefixMatcher.prefixMatches(it) }, jetReference!!.expression)
|
||||
}
|
||||
|
||||
protected fun addAllTypes() {
|
||||
TypesCompletion(parameters, resolveSession, prefixMatcher, { isVisibleDescriptor(it) }).addAllTypes(collector)
|
||||
protected fun addAllClasses(kindFilter: (ClassKind) -> Boolean) {
|
||||
AllClassesCompletion(parameters, resolveSession, prefixMatcher, kindFilter, { isVisibleDescriptor(it) }).collect(collector)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +141,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
if (completeReference) {
|
||||
if (shouldRunOnlyTypeCompletion()) {
|
||||
if (configuration.completeNonImportedDeclarations) {
|
||||
addAllTypes()
|
||||
addAllClasses { !it.isSingleton() }
|
||||
}
|
||||
else {
|
||||
addReferenceVariants(JetScope.TYPE or JetScope.PACKAGE)
|
||||
@@ -164,8 +167,8 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
|
||||
private fun addNonImported() {
|
||||
if (shouldRunTopLevelCompletion()) {
|
||||
addAllTypes()
|
||||
collector.addDescriptorElements(getKotlinTopLevelDeclarations(), suppressAutoInsertion = true)
|
||||
addAllClasses { it != ClassKind.ENUM_ENTRY }
|
||||
collector.addDescriptorElements(getKotlinTopLevelCallables(), suppressAutoInsertion = true)
|
||||
}
|
||||
|
||||
if (shouldRunExtensionsCompletion()) {
|
||||
@@ -223,7 +226,8 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
||||
|
||||
private fun processNonImported(processor: (DeclarationDescriptor) -> Unit) {
|
||||
if (shouldRunTopLevelCompletion()) {
|
||||
getKotlinTopLevelDeclarations().forEach(processor)
|
||||
getKotlinTopLevelCallables().forEach(processor)
|
||||
getKotlinTopLevelObjects().forEach(processor) //TODO: shouldn't it work via inheritors search?
|
||||
}
|
||||
|
||||
if (shouldRunExtensionsCompletion()) {
|
||||
|
||||
Reference in New Issue
Block a user