Auto-import fix also honors visibility
This commit is contained in:
@@ -40,7 +40,8 @@ import org.jetbrains.jet.lang.resolve.calls.smartcasts.DataFlowInfo
|
||||
|
||||
public class KotlinIndicesHelper(private val project: Project,
|
||||
private val resolveSession: ResolveSessionForBodies,
|
||||
private val scope: GlobalSearchScope) {
|
||||
private val scope: GlobalSearchScope,
|
||||
private val visibilityFilter: (DeclarationDescriptor) -> Boolean) {
|
||||
public fun getTopLevelObjects(nameFilter: (String) -> Boolean): Collection<ClassDescriptor> {
|
||||
val allObjectNames = JetTopLevelObjectShortNameIndex.getInstance().getAllKeys(project).stream() +
|
||||
JetFromJavaDescriptorHelper.getPossiblePackageDeclarationsNames(project, scope).stream()
|
||||
@@ -66,7 +67,7 @@ public class KotlinIndicesHelper(private val project: Project,
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
return result.filter(visibilityFilter)
|
||||
}
|
||||
|
||||
public fun getTopLevelCallablesByName(name: String, context: JetExpression /*TODO: to be dropped*/): Collection<CallableDescriptor> {
|
||||
@@ -85,7 +86,7 @@ public class KotlinIndicesHelper(private val project: Project,
|
||||
result.addSourceTopLevelFunctions(name)
|
||||
result.addSourceTopLevelProperties(name)
|
||||
|
||||
return result
|
||||
return result.filter(visibilityFilter)
|
||||
}
|
||||
|
||||
private fun MutableCollection<in FunctionDescriptor>.addSourceTopLevelFunctions(name: String) {
|
||||
@@ -185,6 +186,7 @@ public class KotlinIndicesHelper(private val project: Project,
|
||||
return declarationDescriptors
|
||||
.filterIsInstance(javaClass<CallableDescriptor>())
|
||||
.filter { it.getExtensionReceiverParameter() != null &&
|
||||
visibilityFilter(it) &&
|
||||
ExpressionTypingUtils.checkIsExtensionCallable(receiverValue, it, isInfixCall, bindingContext, dataFlowInfo) }
|
||||
}
|
||||
|
||||
@@ -205,13 +207,13 @@ public class KotlinIndicesHelper(private val project: Project,
|
||||
}
|
||||
|
||||
// Note: Can't search with psi element as analyzer could be built over temp files
|
||||
return ResolveSessionUtils.getClassDescriptorsByFqName(resolveSession.getModuleDescriptor(), classFQName)
|
||||
return ResolveSessionUtils.getClassDescriptorsByFqName(resolveSession.getModuleDescriptor(), classFQName).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())
|
||||
return allDescriptors.filterIsInstance(javaClass<CallableDescriptor>()).filter { it.getExtensionReceiverParameter() == null }
|
||||
return allDescriptors.filterIsInstance(javaClass<CallableDescriptor>()).filter { it.getExtensionReceiverParameter() == null && visibilityFilter(it) }
|
||||
}
|
||||
|
||||
private fun analyzeImportReference(
|
||||
|
||||
@@ -63,7 +63,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
|
||||
protected val project: Project = position.getProject()
|
||||
protected val searchScope: GlobalSearchScope = searchScopeForSourceElementDependencies(parameters.getOriginalFile()) ?: GlobalSearchScope.EMPTY_SCOPE
|
||||
protected val indicesHelper: KotlinIndicesHelper = KotlinIndicesHelper(project, resolveSession, searchScope)
|
||||
protected val indicesHelper: KotlinIndicesHelper = KotlinIndicesHelper(project, resolveSession, searchScope) { isVisibleDescriptor(it) }
|
||||
|
||||
protected fun isVisibleDescriptor(descriptor: DeclarationDescriptor): Boolean {
|
||||
if (configuration.completeNonAccessibleDeclarations) return true
|
||||
@@ -104,13 +104,11 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
|
||||
protected fun getKotlinTopLevelDeclarations(): Collection<DeclarationDescriptor> {
|
||||
val filter = { (name: String) -> prefixMatcher.prefixMatches(name) }
|
||||
return (indicesHelper.getTopLevelCallables(filter, jetReference!!.expression) + indicesHelper.getTopLevelObjects(filter))
|
||||
.filter { isVisibleDescriptor(it) }
|
||||
return indicesHelper.getTopLevelCallables(filter, jetReference!!.expression) + indicesHelper.getTopLevelObjects(filter)
|
||||
}
|
||||
|
||||
protected fun getKotlinExtensions(): Collection<CallableDescriptor> {
|
||||
return indicesHelper.getCallableExtensions({ prefixMatcher.prefixMatches(it) }, jetReference!!.expression)
|
||||
.filter { isVisibleDescriptor(it) }
|
||||
}
|
||||
|
||||
protected fun addAllTypes() {
|
||||
|
||||
@@ -42,7 +42,7 @@ class TypesCompletion(val parameters: CompletionParameters,
|
||||
|
||||
val project = parameters.getOriginalFile().getProject()
|
||||
val searchScope = searchScopeForSourceElementDependencies(parameters.getOriginalFile()) ?: return
|
||||
result.addDescriptorElements(KotlinIndicesHelper(project, resolveSession, searchScope).getClassDescriptors { prefixMatcher.prefixMatches(it) }.filter(visibilityFilter),
|
||||
result.addDescriptorElements(KotlinIndicesHelper(project, resolveSession, searchScope, visibilityFilter).getClassDescriptors { prefixMatcher.prefixMatches(it) },
|
||||
suppressAutoInsertion = true)
|
||||
|
||||
if (!ProjectStructureUtil.isJsKotlinModule(parameters.getOriginalFile() as JetFile)) {
|
||||
|
||||
@@ -41,7 +41,6 @@ import org.jetbrains.jet.plugin.caches.JetShortNamesCache
|
||||
import org.jetbrains.jet.plugin.caches.KotlinIndicesHelper
|
||||
import org.jetbrains.jet.plugin.caches.resolve.*
|
||||
import org.jetbrains.jet.plugin.project.ProjectStructureUtil
|
||||
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
|
||||
import org.jetbrains.jet.plugin.util.JetPsiHeuristicsUtil
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
@@ -51,6 +50,9 @@ import com.intellij.openapi.module.ModuleUtilCore
|
||||
import org.jetbrains.jet.plugin.util.ProjectRootsUtil
|
||||
import org.jetbrains.jet.asJava.unwrapped
|
||||
import org.jetbrains.jet.plugin.search.searchScopeForSourceElementDependencies
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorWithVisibility
|
||||
import org.jetbrains.jet.lang.descriptors.Visibilities
|
||||
|
||||
/**
|
||||
* Check possibility and perform fix for unresolved references.
|
||||
@@ -112,40 +114,41 @@ public class AutoImportFix(element: JetSimpleNameExpression) : JetHintAction<Jet
|
||||
|
||||
val searchScope = searchScopeForSourceElementDependencies(file) ?: return listOf()
|
||||
|
||||
val resolutionScope = resolveSession.resolveToElement(element)[BindingContext.RESOLUTION_SCOPE, element] ?: return listOf()
|
||||
val containingDescriptor = resolutionScope.getContainingDeclaration()
|
||||
|
||||
fun isVisible(descriptor: DeclarationDescriptor): Boolean {
|
||||
if (descriptor is DeclarationDescriptorWithVisibility && containingDescriptor != null) {
|
||||
return Visibilities.isVisible(descriptor, containingDescriptor)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
val result = ArrayList<PrioritizedFqName>()
|
||||
|
||||
val indicesHelper = KotlinIndicesHelper(file.getProject(), resolveSession, searchScope, ::isVisible)
|
||||
|
||||
if (!element.isImportDirectiveExpression() && !JetPsiUtil.isSelectorInQualified(element)) {
|
||||
result.addAll(getClassNames(referenceName, file, searchScope))
|
||||
result.addAll(getTopLevelCallables(referenceName, element, searchScope, resolveSession, file.getProject()))
|
||||
result.addAll(getTopLevelCallables(referenceName, element, indicesHelper))
|
||||
}
|
||||
|
||||
result.addAll(getExtensions(referenceName, element, searchScope, resolveSession, file.getProject()))
|
||||
result.addAll(getExtensions(referenceName, element, indicesHelper))
|
||||
|
||||
return result
|
||||
.filter { ImportInsertHelper.getInstance().needImport(ImportPath(it.fqName, false), file) }
|
||||
.sortBy { it.priority.ordinal() }
|
||||
.sortBy { it.priority }
|
||||
.map { it.fqName }
|
||||
}
|
||||
|
||||
private fun getTopLevelCallables(
|
||||
name: String,
|
||||
context: JetExpression,
|
||||
searchScope: GlobalSearchScope,
|
||||
resolveSession: ResolveSessionForBodies,
|
||||
project: Project
|
||||
): Collection<PrioritizedFqName>
|
||||
= KotlinIndicesHelper(project, resolveSession, searchScope).getTopLevelCallablesByName(name, context)
|
||||
private fun getTopLevelCallables(name: String, context: JetExpression, indicesHelper: KotlinIndicesHelper): Collection<PrioritizedFqName>
|
||||
= indicesHelper.getTopLevelCallablesByName(name, context)
|
||||
.map { PrioritizedFqName(it) }
|
||||
.toSet()
|
||||
|
||||
private fun getExtensions(
|
||||
name: String,
|
||||
expression: JetSimpleNameExpression,
|
||||
searchScope: GlobalSearchScope,
|
||||
resolveSession: ResolveSessionForBodies,
|
||||
project: Project
|
||||
): Collection<PrioritizedFqName>
|
||||
= KotlinIndicesHelper(project, resolveSession, searchScope).getCallableExtensions({ it == name }, expression)
|
||||
private fun getExtensions(name: String, expression: JetSimpleNameExpression, indicesHelper: KotlinIndicesHelper): Collection<PrioritizedFqName>
|
||||
= indicesHelper.getCallableExtensions({ it == name }, expression)
|
||||
.map { PrioritizedFqName(it) }
|
||||
.toSet()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user