Performance fix for Import Member

This commit is contained in:
Valentin Kipyatkov
2016-10-25 19:37:57 +03:00
parent d9ef8aa96f
commit 8c99b0e64c
2 changed files with 48 additions and 25 deletions
@@ -206,28 +206,41 @@ class KotlinIndicesHelper(
.toSet()
}
fun getJvmCallablesByName(name: String): Collection<CallableDescriptor> {
fun processJvmCallablesByName(
name: String,
filter: (PsiMember) -> Boolean,
processor: (CallableDescriptor) -> Unit
) {
val javaDeclarations = PsiShortNamesCache.getInstance(project).getFieldsByName(name, scopeWithoutKotlin).asSequence() +
PsiShortNamesCache.getInstance(project).getMethodsByName(name, scopeWithoutKotlin).asSequence()
return javaDeclarations
.filterNot { it is KtLightElement<*,*> }
.mapNotNull { (it as PsiMember).getJavaMemberDescriptor(resolutionFacade) as? CallableDescriptor }
.filter(descriptorFilter)
.toSet()
val processed = HashSet<CallableDescriptor>()
for (javaDeclaration in javaDeclarations) {
ProgressManager.checkCanceled()
if (javaDeclaration is KtLightElement<*, *>) continue
if (!filter(javaDeclaration as PsiMember)) continue
val descriptor = javaDeclaration.getJavaMemberDescriptor(resolutionFacade) as? CallableDescriptor ?: continue
if (!processed.add(descriptor)) continue
if (!descriptorFilter(descriptor)) continue
processor(descriptor)
}
}
fun getKotlinCallablesByName(name: String): Collection<CallableDescriptor> {
val functions = KotlinFunctionShortNameIndex.getInstance().get(name, project, scope)
.asSequence()
.map { it.descriptor as? CallableDescriptor }
val properties = KotlinPropertyShortNameIndex.getInstance().get(name, project, scope)
.asSequence()
.map { it.descriptor as? CallableDescriptor }
return (functions + properties)
.filterNotNull()
.filter(descriptorFilter)
.toSet()
fun processKotlinCallablesByName(
name: String,
filter: (KtCallableDeclaration) -> Boolean,
processor: (CallableDescriptor) -> Unit
) {
val functions: Sequence<KtCallableDeclaration> = KotlinFunctionShortNameIndex.getInstance().get(name, project, scope).asSequence()
val properties: Sequence<KtCallableDeclaration> = KotlinPropertyShortNameIndex.getInstance().get(name, project, scope).asSequence()
val processed = HashSet<CallableDescriptor>()
for (declaration in functions + properties) {
ProgressManager.checkCanceled()
if (!filter(declaration)) continue
val descriptor = declaration.descriptor as? CallableDescriptor ?: continue
if (!processed.add(descriptor)) continue
if (!descriptorFilter(descriptor)) continue
processor(descriptor)
}
}
fun getKotlinClasses(nameFilter: (String) -> Boolean, kindFilter: (ClassKind) -> Boolean): Collection<ClassDescriptor> {
@@ -28,6 +28,7 @@ import com.intellij.packageDependencies.DependencyValidationManager
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiErrorElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiModifier
import com.intellij.psi.util.PsiModificationTracker
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
@@ -62,7 +63,6 @@ import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.isImportDirectiveExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils.isTopLevelDeclaration
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.callUtil.getParentCall
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
@@ -393,14 +393,24 @@ internal class ImportMemberFix(expression: KtSimpleNameExpression) : ImportFixBa
if (!element.isImportDirectiveExpression() && !isSelectorInQualified(element)) {
val filterByCallType = { descriptor: DeclarationDescriptor -> callTypeAndReceiver.callType.descriptorKindFilter.accepts(descriptor) }
indicesHelper.getKotlinCallablesByName(name)
.filter { it.canBeReferencedViaImport() && !isTopLevelDeclaration(it) }
.filterTo(result, filterByCallType)
val processor = { descriptor: CallableDescriptor ->
if (descriptor.canBeReferencedViaImport() && filterByCallType(descriptor)) {
result.add(descriptor)
}
}
indicesHelper.processKotlinCallablesByName(
name,
filter = { declaration -> (declaration.parent as? KtClassBody)?.parent is KtObjectDeclaration },
processor = processor
)
if (!ProjectStructureUtil.isJsKotlinModule(element.getContainingKtFile())) {
indicesHelper.getJvmCallablesByName(name)
.filter { it.canBeReferencedViaImport() }
.filterTo(result, filterByCallType)
indicesHelper.processJvmCallablesByName(
name,
filter = { it.hasModifierProperty(PsiModifier.STATIC) },
processor = processor
)
}
}
return result