More correct and simple finding of top-level callables
This commit is contained in:
@@ -47,16 +47,13 @@ public class KotlinIndicesHelper(
|
|||||||
private val moduleDescriptor: ModuleDescriptor,
|
private val moduleDescriptor: ModuleDescriptor,
|
||||||
private val visibilityFilter: (DeclarationDescriptor) -> Boolean
|
private val visibilityFilter: (DeclarationDescriptor) -> Boolean
|
||||||
) {
|
) {
|
||||||
public fun getTopLevelCallablesByName(name: String, context: JetExpression /*TODO: to be dropped*/): Collection<CallableDescriptor> {
|
public fun getTopLevelCallablesByName(name: String): Collection<CallableDescriptor> {
|
||||||
val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, context] ?: return listOf()
|
|
||||||
|
|
||||||
val declarations = HashSet<JetNamedDeclaration>()
|
val declarations = HashSet<JetNamedDeclaration>()
|
||||||
declarations.addTopLevelNonExtensionCallablesByName(JetFunctionShortNameIndex.getInstance(), name)
|
declarations.addTopLevelNonExtensionCallablesByName(JetFunctionShortNameIndex.getInstance(), name)
|
||||||
declarations.addTopLevelNonExtensionCallablesByName(JetPropertyShortNameIndex.getInstance(), name)
|
declarations.addTopLevelNonExtensionCallablesByName(JetPropertyShortNameIndex.getInstance(), name)
|
||||||
return declarations.flatMap {
|
return declarations.flatMap {
|
||||||
if (it.getContainingJetFile().isCompiled()) {
|
if (it.getContainingJetFile().isCompiled()) {
|
||||||
val importDirective = JetPsiFactory(project).createImportDirective(it.getFqName().asString())
|
analyzeImportReference(it.getFqName()!!).filterIsInstance<CallableDescriptor>()
|
||||||
analyzeImportReference(importDirective, resolutionScope, BindingTraceContext()).filterIsInstance<CallableDescriptor>()
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(resolutionFacade.resolveToDescriptor(it) as? CallableDescriptor).singletonOrEmptyList()
|
(resolutionFacade.resolveToDescriptor(it) as? CallableDescriptor).singletonOrEmptyList()
|
||||||
@@ -71,15 +68,12 @@ public class KotlinIndicesHelper(
|
|||||||
index.get(name, project, scope).filterTo(this) { it.getParent() is JetFile && it.getReceiverTypeReference() == null }
|
index.get(name, project, scope).filterTo(this) { it.getParent() is JetFile && it.getReceiverTypeReference() == null }
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun getTopLevelCallables(nameFilter: (String) -> Boolean, context: JetExpression /*TODO: to be dropped*/): Collection<CallableDescriptor> {
|
public fun getTopLevelCallables(nameFilter: (String) -> Boolean): Collection<CallableDescriptor> {
|
||||||
val sourceNames = JetTopLevelFunctionFqnNameIndex.getInstance().getAllKeys(project).stream() + JetTopLevelPropertyFqnNameIndex.getInstance().getAllKeys(project).stream()
|
val sourceNames = JetTopLevelFunctionFqnNameIndex.getInstance().getAllKeys(project).stream() + JetTopLevelPropertyFqnNameIndex.getInstance().getAllKeys(project).stream()
|
||||||
val allFqNames = sourceNames.map { FqName(it) }
|
val allFqNames = sourceNames.map { FqName(it) }
|
||||||
|
|
||||||
val jetScope = bindingContext[BindingContext.RESOLUTION_SCOPE, context] ?: return listOf()
|
|
||||||
|
|
||||||
return allFqNames.filter { nameFilter(it.shortName().asString()) }
|
return allFqNames.filter { nameFilter(it.shortName().asString()) }
|
||||||
.toSet()
|
.toSet()
|
||||||
.flatMap { findTopLevelCallables(it, context, jetScope).filter(visibilityFilter) }
|
.flatMap { findTopLevelCallables(it).filter(visibilityFilter) }
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun getCallableExtensions(nameFilter: (String) -> Boolean, expression: JetSimpleNameExpression): Collection<CallableDescriptor> {
|
public fun getCallableExtensions(nameFilter: (String) -> Boolean, expression: JetSimpleNameExpression): Collection<CallableDescriptor> {
|
||||||
@@ -113,12 +107,10 @@ public class KotlinIndicesHelper(
|
|||||||
val expressionType = bindingContext[BindingContext.EXPRESSION_TYPE, receiverExpression]
|
val expressionType = bindingContext[BindingContext.EXPRESSION_TYPE, receiverExpression]
|
||||||
if (expressionType == null || expressionType.isError()) return
|
if (expressionType == null || expressionType.isError()) return
|
||||||
|
|
||||||
val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, receiverExpression] ?: return
|
|
||||||
|
|
||||||
val receiverValue = ExpressionReceiver(receiverExpression, expressionType)
|
val receiverValue = ExpressionReceiver(receiverExpression, expressionType)
|
||||||
|
|
||||||
matchingNames.flatMapTo(this) {
|
matchingNames.flatMapTo(this) {
|
||||||
findSuitableExtensions(it, index, receiverValue, dataFlowInfo, callType, resolutionScope, bindingContext)
|
findSuitableExtensions(it, index, receiverValue, dataFlowInfo, callType, bindingContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -126,7 +118,7 @@ public class KotlinIndicesHelper(
|
|||||||
|
|
||||||
for (receiver in resolutionScope.getImplicitReceiversWithInstance()) {
|
for (receiver in resolutionScope.getImplicitReceiversWithInstance()) {
|
||||||
matchingNames.flatMapTo(this) {
|
matchingNames.flatMapTo(this) {
|
||||||
findSuitableExtensions(it, index, receiver.getValue(), dataFlowInfo, CallType.NORMAL, resolutionScope, bindingContext)
|
findSuitableExtensions(it, index, receiver.getValue(), dataFlowInfo, CallType.NORMAL, bindingContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,13 +132,10 @@ public class KotlinIndicesHelper(
|
|||||||
receiverValue: ReceiverValue,
|
receiverValue: ReceiverValue,
|
||||||
dataFlowInfo: DataFlowInfo,
|
dataFlowInfo: DataFlowInfo,
|
||||||
callType: CallType,
|
callType: CallType,
|
||||||
resolutionScope: JetScope,
|
|
||||||
bindingContext: BindingContext): Stream<CallableDescriptor> {
|
bindingContext: BindingContext): Stream<CallableDescriptor> {
|
||||||
val fqnString = callableFQN.asString()
|
val extensions = index.get(callableFQN.asString(), project, scope).filter { it.getReceiverTypeReference() != null }
|
||||||
val extensions = index.get(fqnString, project, scope).filter { it.getReceiverTypeReference() != null }
|
|
||||||
val descriptors = if (extensions.any { it.getContainingJetFile().isCompiled() } ) {
|
val descriptors = if (extensions.any { it.getContainingJetFile().isCompiled() } ) {
|
||||||
val importDirective = JetPsiFactory(project).createImportDirective(fqnString)
|
analyzeImportReference(callableFQN)
|
||||||
analyzeImportReference(importDirective, resolutionScope, BindingTraceContext())
|
|
||||||
.filterIsInstance<CallableDescriptor>()
|
.filterIsInstance<CallableDescriptor>()
|
||||||
.filter { it.getExtensionReceiverParameter() != null }
|
.filter { it.getExtensionReceiverParameter() != null }
|
||||||
}
|
}
|
||||||
@@ -177,15 +166,15 @@ public class KotlinIndicesHelper(
|
|||||||
.filter(visibilityFilter)
|
.filter(visibilityFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findTopLevelCallables(fqName: FqName, context: JetExpression, jetScope: JetScope): Collection<CallableDescriptor> {
|
private fun findTopLevelCallables(fqName: FqName): Collection<CallableDescriptor> {
|
||||||
val importDirective = JetPsiFactory(context.getProject()).createImportDirective(ImportPath(fqName, false))
|
return analyzeImportReference(fqName)
|
||||||
val allDescriptors = analyzeImportReference(importDirective, jetScope, BindingTraceContext())
|
.filterIsInstance<CallableDescriptor>()
|
||||||
return allDescriptors.filterIsInstance<CallableDescriptor>().filter { it.getExtensionReceiverParameter() == null }
|
.filter { it.getExtensionReceiverParameter() == null }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun analyzeImportReference(
|
private fun analyzeImportReference(fqName: FqName): Collection<DeclarationDescriptor> {
|
||||||
importDirective: JetImportDirective, scope: JetScope, trace: BindingTrace
|
val importDirective = JetPsiFactory(project).createImportDirective(ImportPath(fqName, false))
|
||||||
): Collection<DeclarationDescriptor> {
|
val scope = JetModuleUtil.getSubpackagesOfRootScope(moduleDescriptor)
|
||||||
return QualifiedExpressionResolver().processImportReference(importDirective, scope, scope, null, trace, LookupMode.EVERYTHING)
|
return QualifiedExpressionResolver().processImportReference(importDirective, scope, scope, null, BindingTraceContext(), LookupMode.EVERYTHING)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
|||||||
= configuration.completeNonImportedDeclarations || prefix.length() >= 3
|
= configuration.completeNonImportedDeclarations || prefix.length() >= 3
|
||||||
|
|
||||||
protected fun getKotlinTopLevelCallables(): Collection<DeclarationDescriptor>
|
protected fun getKotlinTopLevelCallables(): Collection<DeclarationDescriptor>
|
||||||
= indicesHelper.getTopLevelCallables({ prefixMatcher.prefixMatches(it) }, reference!!.expression)
|
= indicesHelper.getTopLevelCallables({ prefixMatcher.prefixMatches(it) })
|
||||||
|
|
||||||
protected fun getKotlinExtensions(): Collection<CallableDescriptor>
|
protected fun getKotlinExtensions(): Collection<CallableDescriptor>
|
||||||
= indicesHelper.getCallableExtensions({ prefixMatcher.prefixMatches(it) }, reference!!.expression)
|
= indicesHelper.getCallableExtensions({ prefixMatcher.prefixMatches(it) }, reference!!.expression)
|
||||||
|
|||||||
@@ -142,20 +142,14 @@ public class AutoImportFix(element: JetSimpleNameExpression) : JetHintAction<Jet
|
|||||||
|
|
||||||
if (!element.isImportDirectiveExpression() && !JetPsiUtil.isSelectorInQualified(element)) {
|
if (!element.isImportDirectiveExpression() && !JetPsiUtil.isSelectorInQualified(element)) {
|
||||||
getClasses(referenceName, file, searchScope).filterTo(result, ::isVisible)
|
getClasses(referenceName, file, searchScope).filterTo(result, ::isVisible)
|
||||||
result.addAll(getTopLevelCallables(referenceName, element, indicesHelper))
|
result.addAll(indicesHelper.getTopLevelCallablesByName(referenceName))
|
||||||
}
|
}
|
||||||
|
|
||||||
result.addAll(getExtensions(referenceName, element, indicesHelper))
|
result.addAll(indicesHelper.getCallableExtensions({ it == referenceName }, element))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTopLevelCallables(name: String, context: JetExpression, indicesHelper: KotlinIndicesHelper): Collection<DeclarationDescriptor>
|
|
||||||
= indicesHelper.getTopLevelCallablesByName(name, context)
|
|
||||||
|
|
||||||
private fun getExtensions(name: String, expression: JetSimpleNameExpression, indicesHelper: KotlinIndicesHelper): Collection<DeclarationDescriptor>
|
|
||||||
= indicesHelper.getCallableExtensions({ it == name }, expression)
|
|
||||||
|
|
||||||
private fun getClasses(name: String, file: JetFile, searchScope: GlobalSearchScope): Collection<DeclarationDescriptor>
|
private fun getClasses(name: String, file: JetFile, searchScope: GlobalSearchScope): Collection<DeclarationDescriptor>
|
||||||
= getShortNamesCache(file).getClassesByName(name, searchScope)
|
= getShortNamesCache(file).getClassesByName(name, searchScope)
|
||||||
.map { element.getResolutionFacade().psiClassToDescriptor(it) }
|
.map { element.getResolutionFacade().psiClassToDescriptor(it) }
|
||||||
|
|||||||
Reference in New Issue
Block a user