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,
|
public class KotlinIndicesHelper(private val project: Project,
|
||||||
private val resolveSession: ResolveSessionForBodies,
|
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> {
|
public fun getTopLevelObjects(nameFilter: (String) -> Boolean): Collection<ClassDescriptor> {
|
||||||
val allObjectNames = JetTopLevelObjectShortNameIndex.getInstance().getAllKeys(project).stream() +
|
val allObjectNames = JetTopLevelObjectShortNameIndex.getInstance().getAllKeys(project).stream() +
|
||||||
JetFromJavaDescriptorHelper.getPossiblePackageDeclarationsNames(project, scope).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> {
|
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.addSourceTopLevelFunctions(name)
|
||||||
result.addSourceTopLevelProperties(name)
|
result.addSourceTopLevelProperties(name)
|
||||||
|
|
||||||
return result
|
return result.filter(visibilityFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableCollection<in FunctionDescriptor>.addSourceTopLevelFunctions(name: String) {
|
private fun MutableCollection<in FunctionDescriptor>.addSourceTopLevelFunctions(name: String) {
|
||||||
@@ -185,6 +186,7 @@ public class KotlinIndicesHelper(private val project: Project,
|
|||||||
return declarationDescriptors
|
return declarationDescriptors
|
||||||
.filterIsInstance(javaClass<CallableDescriptor>())
|
.filterIsInstance(javaClass<CallableDescriptor>())
|
||||||
.filter { it.getExtensionReceiverParameter() != null &&
|
.filter { it.getExtensionReceiverParameter() != null &&
|
||||||
|
visibilityFilter(it) &&
|
||||||
ExpressionTypingUtils.checkIsExtensionCallable(receiverValue, it, isInfixCall, bindingContext, dataFlowInfo) }
|
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
|
// 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> {
|
private fun findTopLevelCallables(fqName: FqName, context: JetExpression, jetScope: JetScope): Collection<CallableDescriptor> {
|
||||||
val importDirective = JetPsiFactory(context.getProject()).createImportDirective(ImportPath(fqName, false))
|
val importDirective = JetPsiFactory(context.getProject()).createImportDirective(ImportPath(fqName, false))
|
||||||
val allDescriptors = analyzeImportReference(importDirective, jetScope, BindingTraceContext(), resolveSession.getModuleDescriptor())
|
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(
|
private fun analyzeImportReference(
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
|||||||
|
|
||||||
protected val project: Project = position.getProject()
|
protected val project: Project = position.getProject()
|
||||||
protected val searchScope: GlobalSearchScope = searchScopeForSourceElementDependencies(parameters.getOriginalFile()) ?: GlobalSearchScope.EMPTY_SCOPE
|
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 {
|
protected fun isVisibleDescriptor(descriptor: DeclarationDescriptor): Boolean {
|
||||||
if (configuration.completeNonAccessibleDeclarations) return true
|
if (configuration.completeNonAccessibleDeclarations) return true
|
||||||
@@ -104,13 +104,11 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
|||||||
|
|
||||||
protected fun getKotlinTopLevelDeclarations(): Collection<DeclarationDescriptor> {
|
protected fun getKotlinTopLevelDeclarations(): Collection<DeclarationDescriptor> {
|
||||||
val filter = { (name: String) -> prefixMatcher.prefixMatches(name) }
|
val filter = { (name: String) -> prefixMatcher.prefixMatches(name) }
|
||||||
return (indicesHelper.getTopLevelCallables(filter, jetReference!!.expression) + indicesHelper.getTopLevelObjects(filter))
|
return indicesHelper.getTopLevelCallables(filter, jetReference!!.expression) + indicesHelper.getTopLevelObjects(filter)
|
||||||
.filter { isVisibleDescriptor(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun getKotlinExtensions(): Collection<CallableDescriptor> {
|
protected fun getKotlinExtensions(): Collection<CallableDescriptor> {
|
||||||
return indicesHelper.getCallableExtensions({ prefixMatcher.prefixMatches(it) }, jetReference!!.expression)
|
return indicesHelper.getCallableExtensions({ prefixMatcher.prefixMatches(it) }, jetReference!!.expression)
|
||||||
.filter { isVisibleDescriptor(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun addAllTypes() {
|
protected fun addAllTypes() {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class TypesCompletion(val parameters: CompletionParameters,
|
|||||||
|
|
||||||
val project = parameters.getOriginalFile().getProject()
|
val project = parameters.getOriginalFile().getProject()
|
||||||
val searchScope = searchScopeForSourceElementDependencies(parameters.getOriginalFile()) ?: return
|
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)
|
suppressAutoInsertion = true)
|
||||||
|
|
||||||
if (!ProjectStructureUtil.isJsKotlinModule(parameters.getOriginalFile() as JetFile)) {
|
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.KotlinIndicesHelper
|
||||||
import org.jetbrains.jet.plugin.caches.resolve.*
|
import org.jetbrains.jet.plugin.caches.resolve.*
|
||||||
import org.jetbrains.jet.plugin.project.ProjectStructureUtil
|
import org.jetbrains.jet.plugin.project.ProjectStructureUtil
|
||||||
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies
|
|
||||||
import org.jetbrains.jet.plugin.util.JetPsiHeuristicsUtil
|
import org.jetbrains.jet.plugin.util.JetPsiHeuristicsUtil
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
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.plugin.util.ProjectRootsUtil
|
||||||
import org.jetbrains.jet.asJava.unwrapped
|
import org.jetbrains.jet.asJava.unwrapped
|
||||||
import org.jetbrains.jet.plugin.search.searchScopeForSourceElementDependencies
|
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.
|
* 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 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 result = ArrayList<PrioritizedFqName>()
|
||||||
|
|
||||||
|
val indicesHelper = KotlinIndicesHelper(file.getProject(), resolveSession, searchScope, ::isVisible)
|
||||||
|
|
||||||
if (!element.isImportDirectiveExpression() && !JetPsiUtil.isSelectorInQualified(element)) {
|
if (!element.isImportDirectiveExpression() && !JetPsiUtil.isSelectorInQualified(element)) {
|
||||||
result.addAll(getClassNames(referenceName, file, searchScope))
|
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
|
return result
|
||||||
.filter { ImportInsertHelper.getInstance().needImport(ImportPath(it.fqName, false), file) }
|
.filter { ImportInsertHelper.getInstance().needImport(ImportPath(it.fqName, false), file) }
|
||||||
.sortBy { it.priority.ordinal() }
|
.sortBy { it.priority }
|
||||||
.map { it.fqName }
|
.map { it.fqName }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTopLevelCallables(
|
private fun getTopLevelCallables(name: String, context: JetExpression, indicesHelper: KotlinIndicesHelper): Collection<PrioritizedFqName>
|
||||||
name: String,
|
= indicesHelper.getTopLevelCallablesByName(name, context)
|
||||||
context: JetExpression,
|
|
||||||
searchScope: GlobalSearchScope,
|
|
||||||
resolveSession: ResolveSessionForBodies,
|
|
||||||
project: Project
|
|
||||||
): Collection<PrioritizedFqName>
|
|
||||||
= KotlinIndicesHelper(project, resolveSession, searchScope).getTopLevelCallablesByName(name, context)
|
|
||||||
.map { PrioritizedFqName(it) }
|
.map { PrioritizedFqName(it) }
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
private fun getExtensions(
|
private fun getExtensions(name: String, expression: JetSimpleNameExpression, indicesHelper: KotlinIndicesHelper): Collection<PrioritizedFqName>
|
||||||
name: String,
|
= indicesHelper.getCallableExtensions({ it == name }, expression)
|
||||||
expression: JetSimpleNameExpression,
|
|
||||||
searchScope: GlobalSearchScope,
|
|
||||||
resolveSession: ResolveSessionForBodies,
|
|
||||||
project: Project
|
|
||||||
): Collection<PrioritizedFqName>
|
|
||||||
= KotlinIndicesHelper(project, resolveSession, searchScope).getCallableExtensions({ it == name }, expression)
|
|
||||||
.map { PrioritizedFqName(it) }
|
.map { PrioritizedFqName(it) }
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user