Top-level callables are added one by one

This commit is contained in:
Valentin Kipyatkov
2015-11-06 14:19:45 +03:00
parent 5d56339aba
commit 63b5966212
4 changed files with 38 additions and 25 deletions
@@ -79,23 +79,27 @@ public class ShadowedDeclarationsFilter(
.flatMap { group -> filterEqualSignatureGroup(group) }
}
public fun <TDescriptor : DeclarationDescriptor> filterNonImported(
declarations: Collection<TDescriptor>,
public fun <TDescriptor : DeclarationDescriptor> createNonImportedDeclarationsFilter(
importedDeclarations: Collection<DeclarationDescriptor>
): Collection<TDescriptor> {
): (Collection<TDescriptor>) -> Collection<TDescriptor> {
val importedDeclarationsSet = importedDeclarations.toSet()
val nonImportedDeclarations = declarations.filter { it !in importedDeclarationsSet }
val importedDeclarationsBySignature = importedDeclarationsSet.groupBy { signature(it) }
val notShadowed = HashSet<DeclarationDescriptor>()
// same signature non-imported declarations from different packages do not shadow each other
for ((pair, group) in nonImportedDeclarations.groupBy { signature(it) to packageName(it) }) {
val imported = importedDeclarationsBySignature[pair.first]
val all = if (imported != null) group + imported else group
notShadowed.addAll(filterEqualSignatureGroup(all, descriptorsToImport = group))
return filter@ { declarations ->
// optimization
if (declarations.size == 1 && importedDeclarationsBySignature[signature(declarations.single())] == null) return@filter declarations
val nonImportedDeclarations = declarations.filter { it !in importedDeclarationsSet }
val notShadowed = HashSet<DeclarationDescriptor>()
// same signature non-imported declarations from different packages do not shadow each other
for ((pair, group) in nonImportedDeclarations.groupBy { signature(it) to packageName(it) }) {
val imported = importedDeclarationsBySignature[pair.first]
val all = if (imported != null) group + imported else group
notShadowed.addAll(filterEqualSignatureGroup(all, descriptorsToImport = group))
}
declarations.filter { it in notShadowed }
}
return declarations.filter { it in notShadowed }
}
private fun signature(descriptor: DeclarationDescriptor): Any {
@@ -242,7 +242,10 @@ class BasicCompletionSession(
private fun completeNonImported(lookupElementFactory: LookupElementFactory) {
if (shouldCompleteTopLevelCallablesFromIndex()) {
collector.addDescriptorElements(getTopLevelCallables(), lookupElementFactory, notImported = true)
processTopLevelCallables {
collector.addDescriptorElements(it, lookupElementFactory, notImported = true)
flushToResultSet()
}
}
val classKindFilter: ((ClassKind) -> Boolean)?
@@ -337,7 +337,9 @@ abstract class CompletionSession(
if (shadowedDeclarationsFilter != null) {
variants = shadowedDeclarationsFilter.filter(variants)
notImportedExtensions = shadowedDeclarationsFilter.filterNonImported(notImportedExtensions, variants)
notImportedExtensions = shadowedDeclarationsFilter
.createNonImportedDeclarationsFilter<CallableDescriptor>(importedDeclarations = variants)
.invoke(notImportedExtensions)
}
if (configuration.filterOutJavaGettersAndSetters) {
@@ -394,10 +396,17 @@ abstract class CompletionSession(
return callTypeAndReceiver.receiver == null
}
protected fun getTopLevelCallables(): Collection<CallableDescriptor> {
val result = LinkedHashSet<CallableDescriptor>()
indicesHelper(true).processTopLevelCallables({ prefixMatcher.prefixMatches(it) }) { result.add(it) }
return result.filterShadowedNonImported()
protected fun processTopLevelCallables(processor: (CallableDescriptor) -> Unit) {
val shadowedFilter = ShadowedDeclarationsFilter.create(bindingContext, resolutionFacade, nameExpression!!, callTypeAndReceiver)
?.createNonImportedDeclarationsFilter<CallableDescriptor>(referenceVariants!!.imported)
indicesHelper(true).processTopLevelCallables({ prefixMatcher.prefixMatches(it) }) {
if (shadowedFilter != null) {
shadowedFilter(listOf(it)).singleOrNull()?.let(processor)
}
else {
processor(it)
}
}
}
protected fun CallTypeAndReceiver<*, *>.shouldCompleteCallableExtensions(): Boolean {
@@ -405,11 +414,6 @@ abstract class CompletionSession(
&& this !is CallTypeAndReceiver.IMPORT_DIRECTIVE
}
private fun Collection<CallableDescriptor>.filterShadowedNonImported(): Collection<CallableDescriptor> {
val filter = ShadowedDeclarationsFilter.create(bindingContext, resolutionFacade, nameExpression!!, callTypeAndReceiver)
return if (filter != null) filter.filterNonImported(this, referenceVariants!!.imported) else this
}
protected fun addClassesFromIndex(kindFilter: (ClassKind) -> Boolean) {
AllClassesCompletion(parameters, indicesHelper(true), prefixMatcher, resolutionFacade, kindFilter)
.collect(
@@ -120,8 +120,10 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
}
if (shouldCompleteTopLevelCallablesFromIndex()) {
getTopLevelCallables().forEach { collector.addElements(filter(it, lookupElementFactory), notImported = true) }
flushToResultSet()
processTopLevelCallables {
collector.addElements(filter(it, lookupElementFactory), notImported = true)
flushToResultSet()
}
}
if (position.getContainingFile() is KtCodeFragment) {