Add static members into the list one by one

This commit is contained in:
Valentin Kipyatkov
2015-11-06 13:07:58 +03:00
parent c38039144f
commit ae9482a36c
3 changed files with 47 additions and 37 deletions
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
import org.jetbrains.kotlin.idea.core.targetDescriptors import org.jetbrains.kotlin.idea.core.targetDescriptors
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtObjectDeclaration
@@ -87,23 +88,26 @@ class StaticMembersCompletion(
//TODO: better presentation for lookup elements from imports too //TODO: better presentation for lookup elements from imports too
//TODO: from the same file //TODO: from the same file
fun membersFromIndices(indicesHelper: KotlinIndicesHelper): Collection<DeclarationDescriptor> { fun processMembersFromIndices(indicesHelper: KotlinIndicesHelper, processor: (DeclarationDescriptor) -> Unit) {
val descriptorKindFilter = DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions val descriptorKindFilter = DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions
val nameFilter: (String) -> Boolean = { prefixMatcher.prefixMatches(it) } val nameFilter: (String) -> Boolean = { prefixMatcher.prefixMatches(it) }
val result = ArrayList<DeclarationDescriptor>() val filter = { declaration: KtCallableDeclaration, objectDeclaration: KtObjectDeclaration ->
!declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD) && objectDeclaration.isTopLevelOrCompanion()
}
indicesHelper.processObjectMembers(descriptorKindFilter, nameFilter, filter) {
if (it !in alreadyAdded) { //TODO: substitution
processor(it)
}
}
if (isJvmModule) { if (isJvmModule) {
indicesHelper.getJavaStaticMembers(descriptorKindFilter, nameFilter).filterTo(result) { it !in alreadyAdded } //TODO: substitution indicesHelper.processJavaStaticMembers(descriptorKindFilter, nameFilter){
if (it !in alreadyAdded) { //TODO: substitution
processor(it)
}
}
} }
indicesHelper.getObjectMembers(descriptorKindFilter, nameFilter) filter@ { declaration, objectDeclaration ->
!declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD) && objectDeclaration.isTopLevelOrCompanion()
}.filterTo(result) {
it !in alreadyAdded //TODO: substitution
}
return result
} }
private fun KtObjectDeclaration.isTopLevelOrCompanion(): Boolean { private fun KtObjectDeclaration.isTopLevelOrCompanion(): Boolean {
@@ -125,8 +129,9 @@ class StaticMembersCompletion(
fun completeFromIndices(indicesHelper: KotlinIndicesHelper, collector: LookupElementsCollector) { fun completeFromIndices(indicesHelper: KotlinIndicesHelper, collector: LookupElementsCollector) {
val factory = decoratedLookupElementFactory(ItemPriority.STATIC_MEMBER) val factory = decoratedLookupElementFactory(ItemPriority.STATIC_MEMBER)
membersFromIndices(indicesHelper) processMembersFromIndices(indicesHelper) {
.flatMap { factory.createStandardLookupElementsForDescriptor(it, useReceiverTypes = true) } factory.createStandardLookupElementsForDescriptor(it, useReceiverTypes = true).forEach { collector.addElement(it) }
.forEach { collector.addElement(it) } collector.flushToResultSet()
}
} }
} }
@@ -137,9 +137,12 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
if (staticMembersCompletion != null && configuration.completeStaticMembers) { if (staticMembersCompletion != null && configuration.completeStaticMembers) {
val decoratedFactory = staticMembersCompletion.decoratedLookupElementFactory(ItemPriority.STATIC_MEMBER) val decoratedFactory = staticMembersCompletion.decoratedLookupElementFactory(ItemPriority.STATIC_MEMBER)
staticMembersCompletion.membersFromIndices(indicesHelper(false)) staticMembersCompletion.processMembersFromIndices(indicesHelper(false)) {
.flatMap { filter(it, decoratedFactory) } filter(it, decoratedFactory).forEach {
.forEach { collector.addElement(it) } collector.addElement(it)
flushToResultSet()
}
}
} }
} }
} }
@@ -197,14 +197,13 @@ public class KotlinIndicesHelper(
.filter(descriptorFilter) .filter(descriptorFilter)
} }
public fun getObjectMembers( public fun processObjectMembers(
descriptorKindFilter: DescriptorKindFilter, descriptorKindFilter: DescriptorKindFilter,
nameFilter: (String) -> Boolean, nameFilter: (String) -> Boolean,
filter: (KtCallableDeclaration, KtObjectDeclaration) -> Boolean filter: (KtCallableDeclaration, KtObjectDeclaration) -> Boolean,
): Collection<CallableDescriptor> { processor: (DeclarationDescriptor) -> Unit
val result = LinkedHashSet<CallableDescriptor>() ) {
fun processIndex(index: StringStubIndexExtension<out KtCallableDeclaration>) {
fun addFromIndex(index: StringStubIndexExtension<out KtCallableDeclaration>) {
for (name in index.getAllKeys(project)) { for (name in index.getAllKeys(project)) {
ProgressManager.checkCanceled() ProgressManager.checkCanceled()
if (!nameFilter(name)) continue if (!nameFilter(name)) continue
@@ -214,24 +213,28 @@ public class KotlinIndicesHelper(
if (objectDeclaration.isObjectLiteral()) continue if (objectDeclaration.isObjectLiteral()) continue
if (!visibilityFilterMayIncludeAccessible && declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue if (!visibilityFilterMayIncludeAccessible && declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue
if (!filter(declaration, objectDeclaration)) continue if (!filter(declaration, objectDeclaration)) continue
declaration.resolveToDescriptorsWithHack().filterTo(result) { descriptorKindFilter.accepts(it) && descriptorFilter(it) } for (descriptor in declaration.resolveToDescriptorsWithHack()) {
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
processor(descriptor)
}
}
} }
} }
} }
if (descriptorKindFilter.kindMask.and(DescriptorKindFilter.FUNCTIONS_MASK) != 0) { if (descriptorKindFilter.kindMask.and(DescriptorKindFilter.FUNCTIONS_MASK) != 0) {
addFromIndex(KotlinFunctionShortNameIndex.getInstance()) processIndex(KotlinFunctionShortNameIndex.getInstance())
} }
if (descriptorKindFilter.kindMask.and(DescriptorKindFilter.VARIABLES_MASK) != 0) { if (descriptorKindFilter.kindMask.and(DescriptorKindFilter.VARIABLES_MASK) != 0) {
addFromIndex(KotlinPropertyShortNameIndex.getInstance()) processIndex(KotlinPropertyShortNameIndex.getInstance())
} }
return result
} }
public fun getJavaStaticMembers(descriptorKindFilter: DescriptorKindFilter, nameFilter: (String) -> Boolean): Collection<CallableDescriptor> { public fun processJavaStaticMembers(
val result = LinkedHashSet<CallableDescriptor>() descriptorKindFilter: DescriptorKindFilter,
nameFilter: (String) -> Boolean,
processor: (DeclarationDescriptor) -> Unit
) {
val idFilter = IdFilter.getProjectIdFilter(resolutionFacade.project, false) val idFilter = IdFilter.getProjectIdFilter(resolutionFacade.project, false)
val shortNamesCache = PsiShortNamesCache.getInstance(project) val shortNamesCache = PsiShortNamesCache.getInstance(project)
@@ -246,12 +249,13 @@ public class KotlinIndicesHelper(
val descriptor = method.getJavaMethodDescriptor(resolutionFacade) ?: continue val descriptor = method.getJavaMethodDescriptor(resolutionFacade) ?: continue
val container = descriptor.containingDeclaration as? ClassDescriptor ?: continue val container = descriptor.containingDeclaration as? ClassDescriptor ?: continue
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) { if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
result.add(descriptor) processor(descriptor)
val samAdapter = container.staticScope.getContributedFunctions(descriptor.name, NoLookupLocation.FROM_IDE) // SAM-adapter
container.staticScope.getContributedFunctions(descriptor.name, NoLookupLocation.FROM_IDE)
.filterIsInstance<SamAdapterDescriptor<*>>() .filterIsInstance<SamAdapterDescriptor<*>>()
.firstOrNull { it.originForSam.original == descriptor.original } .firstOrNull { it.originForSam.original == descriptor.original }
result.addIfNotNull(samAdapter) ?.let { processor(it) }
} }
} }
true true
@@ -267,14 +271,12 @@ public class KotlinIndicesHelper(
if (!visibilityFilterMayIncludeAccessible && field.hasModifierProperty(PsiModifier.PRIVATE)) continue if (!visibilityFilterMayIncludeAccessible && field.hasModifierProperty(PsiModifier.PRIVATE)) continue
val descriptor = field.getJavaFieldDescriptor() ?: continue val descriptor = field.getJavaFieldDescriptor() ?: continue
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) { if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
result.add(descriptor) processor(descriptor)
} }
} }
true true
} }
shortNamesCache.processAllFieldNames(fieldNamesProcessor, scope, idFilter) shortNamesCache.processAllFieldNames(fieldNamesProcessor, scope, idFilter)
return result
} }
private fun findTopLevelCallables(fqName: FqName): Collection<CallableDescriptor> { private fun findTopLevelCallables(fqName: FqName): Collection<CallableDescriptor> {