KT-13266 Non-imported type aliases do not appear in completion

#KT-13266 Fixed
This commit is contained in:
Valentin Kipyatkov
2016-08-31 20:15:57 +03:00
parent fcce1e3838
commit 50a0f9a4a7
14 changed files with 124 additions and 40 deletions
@@ -39,11 +39,9 @@ import org.jetbrains.kotlin.idea.util.substituteExtensionIfCallable
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.isHiddenInResolution
import org.jetbrains.kotlin.resolve.lazy.ResolveSessionUtils
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addIfNotNull
@@ -74,7 +72,7 @@ class KotlinIndicesHelper(
declarations.addTopLevelNonExtensionCallablesByName(KotlinFunctionShortNameIndex.getInstance(), name)
declarations.addTopLevelNonExtensionCallablesByName(KotlinPropertyShortNameIndex.getInstance(), name)
return declarations
.flatMap { it.resolveToDescriptorsWithHack() }
.flatMap { it.resolveToDescriptorsWithHack<CallableDescriptor>() }
.filter { descriptorFilter(it) }
}
@@ -88,8 +86,7 @@ class KotlinIndicesHelper(
fun getTopLevelExtensionOperatorsByName(name: String): Collection<FunctionDescriptor> {
return KotlinFunctionShortNameIndex.getInstance().get(name, project, scope)
.filter { it.parent is KtFile && it.receiverTypeReference != null && it.hasModifier(KtTokens.OPERATOR_KEYWORD) }
.flatMap { it.resolveToDescriptorsWithHack() }
.filterIsInstance<FunctionDescriptor>()
.flatMap { it.resolveToDescriptorsWithHack<FunctionDescriptor>() }
.filter { descriptorFilter(it) && it.extensionReceiverParameter != null }
.distinct()
}
@@ -97,8 +94,7 @@ class KotlinIndicesHelper(
fun getMemberOperatorsByName(name: String): Collection<FunctionDescriptor> {
return KotlinFunctionShortNameIndex.getInstance().get(name, project, scope)
.filter { it.parent is KtClassBody && it.receiverTypeReference == null && it.hasModifier(KtTokens.OPERATOR_KEYWORD) }
.flatMap { it.resolveToDescriptorsWithHack() }
.filterIsInstance<FunctionDescriptor>()
.flatMap { it.resolveToDescriptorsWithHack<FunctionDescriptor>() }
.filter { descriptorFilter(it) && it.extensionReceiverParameter == null }
.distinct()
}
@@ -113,7 +109,7 @@ class KotlinIndicesHelper(
if (declaration.receiverTypeReference != null) continue
if (filterOutPrivate && declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue
for (descriptor in declaration.resolveToDescriptorsWithHack()) {
for (descriptor in declaration.resolveToDescriptorsWithHack<CallableDescriptor>()) {
if (descriptorFilter(descriptor)) {
processor(descriptor)
}
@@ -193,7 +189,7 @@ class KotlinIndicesHelper(
}
}
declarations.forEach { it.resolveToDescriptorsWithHack().forEach(::processDescriptor) }
declarations.forEach { it.resolveToDescriptorsWithHack<CallableDescriptor>().forEach(::processDescriptor) }
return result
}
@@ -229,26 +225,34 @@ class KotlinIndicesHelper(
}
fun getKotlinClasses(nameFilter: (String) -> Boolean, kindFilter: (ClassKind) -> Boolean): Collection<ClassDescriptor> {
return KotlinFullClassNameIndex.getInstance().getAllKeys(project).asSequence()
.map { FqName(it) }
val index = KotlinFullClassNameIndex.getInstance()
return index.getAllKeys(project).asSequence()
.filter {
ProgressManager.checkCanceled()
nameFilter(it.shortName().asString())
nameFilter(it.substringAfterLast('.'))
}
.toList()
.flatMap { getClassDescriptorsByFQName(it, kindFilter) }
.flatMap { fqName ->
index[fqName, project, scope]
.flatMap { it.resolveToDescriptorsWithHack<ClassDescriptor>() }
}
.filter { kindFilter(it.kind) && descriptorFilter(it) }
}
private fun getClassDescriptorsByFQName(classFQName: FqName, kindFilter: (ClassKind) -> Boolean): Collection<ClassDescriptor> {
val declarations = KotlinFullClassNameIndex.getInstance()[classFQName.asString(), project, scope]
fun getTopLevelTypeAliases(nameFilter: (String) -> Boolean): Collection<TypeAliasDescriptor> {
val index = KotlinTopLevelTypeAliasFqNameIndex.getInstance()
return index.getAllKeys(project).asSequence()
.filter {
ProgressManager.checkCanceled()
nameFilter(it.substringAfterLast('.'))
}
.toList()
.flatMap { fqName ->
index[fqName, project, scope]
.flatMap { it.resolveToDescriptorsWithHack<TypeAliasDescriptor>() }
if (declarations.isEmpty()) {
// This fqn is absent in caches, dead or not in scope
return emptyList()
}
// Note: Can't search with psi element as analyzer could be built over temp files
return ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(moduleDescriptor, classFQName) { kindFilter(it!!.kind) }
}
.filter(descriptorFilter)
}
@@ -268,7 +272,7 @@ class KotlinIndicesHelper(
if (objectDeclaration.isObjectLiteral()) continue
if (filterOutPrivate && declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue
if (!filter(declaration, objectDeclaration)) continue
for (descriptor in declaration.resolveToDescriptorsWithHack()) {
for (descriptor in declaration.resolveToDescriptorsWithHack<CallableDescriptor>()) {
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
processor(descriptor)
}
@@ -337,13 +341,13 @@ class KotlinIndicesHelper(
return JavaProjectCodeInsightSettings.getSettings(project).isExcluded(fqName)
}
private fun KtCallableDeclaration.resolveToDescriptorsWithHack(): Collection<CallableDescriptor> {
private inline fun <reified TDescriptor : Any> KtNamedDeclaration.resolveToDescriptorsWithHack(): Collection<TDescriptor> {
if (getContainingKtFile().isCompiled) { //TODO: it's temporary while resolveToDescriptor does not work for compiled declarations
return resolutionFacade.resolveImportReference(moduleDescriptor, fqName!!).filterIsInstance<CallableDescriptor>()
return resolutionFacade.resolveImportReference(moduleDescriptor, fqName!!).filterIsInstance<TDescriptor>()
}
else {
val translatedDeclaration = declarationTranslator(this) ?: return emptyList()
return (resolutionFacade.resolveToDescriptor(translatedDeclaration) as? CallableDescriptor).singletonOrEmptyList()
return (resolutionFacade.resolveToDescriptor(translatedDeclaration) as? TDescriptor).singletonOrEmptyList()
}
}
}