Complete type instantiation items after "by"
This commit is contained in:
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.resolve.ideService
|
||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||
import org.jetbrains.kotlin.idea.util.fuzzyExtensionReceiverType
|
||||
import org.jetbrains.kotlin.idea.util.fuzzyReturnType
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
@@ -63,6 +64,12 @@ data class ItemOptions(val starPrefix: Boolean) {
|
||||
interface ByTypeFilter {
|
||||
fun matchingSubstitutor(descriptorType: FuzzyType): TypeSubstitutor?
|
||||
|
||||
val fuzzyType: FuzzyType?
|
||||
get() = null
|
||||
|
||||
val multipleFuzzyTypes: Collection<FuzzyType>
|
||||
get() = fuzzyType.singletonOrEmptyList()
|
||||
|
||||
object All : ByTypeFilter {
|
||||
override fun matchingSubstitutor(descriptorType: FuzzyType) = TypeSubstitutor.EMPTY
|
||||
}
|
||||
@@ -72,7 +79,7 @@ interface ByTypeFilter {
|
||||
}
|
||||
}
|
||||
|
||||
class ByExpectedTypeFilter(val fuzzyType: FuzzyType) : ByTypeFilter {
|
||||
class ByExpectedTypeFilter(override val fuzzyType: FuzzyType) : ByTypeFilter {
|
||||
override fun matchingSubstitutor(descriptorType: FuzzyType) = descriptorType.checkIsSubtypeOf(fuzzyType)
|
||||
|
||||
override fun equals(other: Any?) = other is ByExpectedTypeFilter && fuzzyType == other.fuzzyType
|
||||
@@ -118,7 +125,10 @@ class ExpectedInfo(
|
||||
}
|
||||
|
||||
val ExpectedInfo.fuzzyType: FuzzyType?
|
||||
get() = (this.filter as? ByExpectedTypeFilter)?.fuzzyType
|
||||
get() = filter.fuzzyType
|
||||
|
||||
val ExpectedInfo.multipleFuzzyTypes: Collection<FuzzyType>
|
||||
get() = filter.multipleFuzzyTypes
|
||||
|
||||
sealed class ArgumentPositionData(val function: FunctionDescriptor, val callType: Call.CallType) : ExpectedInfo.AdditionalData {
|
||||
class Positional(
|
||||
@@ -632,6 +642,25 @@ class ExpectedInfos(
|
||||
TypeSubstitutor.createChainedSubstitutor(setOperatorSubstitutor.substitution,
|
||||
setParamTypeSubstitutor.substitution).substitution)
|
||||
}
|
||||
|
||||
override val multipleFuzzyTypes: Collection<FuzzyType> by lazy {
|
||||
val result = ArrayList<FuzzyType>()
|
||||
|
||||
for (classDescriptor in typesWithGetDetector.classesWithMemberOperators) {
|
||||
val type = classDescriptor.defaultType
|
||||
val typeParameters = classDescriptor.declaredTypeParameters
|
||||
val substitutor = matchingSubstitutor(FuzzyType(type, typeParameters)) ?: continue
|
||||
result.add(FuzzyType(substitutor.substitute(type, Variance.INVARIANT)!!, typeParameters))
|
||||
}
|
||||
|
||||
for (extensionOperator in typesWithGetDetector.extensionOperators) {
|
||||
val receiverType = extensionOperator.fuzzyExtensionReceiverType()!!
|
||||
val substitutor = matchingSubstitutor(receiverType) ?: continue
|
||||
result.add(FuzzyType(substitutor.substitute(receiverType.type, Variance.INVARIANT)!!, receiverType.freeParameters))
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
return listOf(ExpectedInfo(byTypeFilter, null, null))
|
||||
//TODO: special items for "Delegates...."
|
||||
|
||||
@@ -42,10 +42,7 @@ 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.KtCallableDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.isHiddenInResolution
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSessionUtils
|
||||
@@ -59,6 +56,7 @@ class KotlinIndicesHelper(
|
||||
private val resolutionFacade: ResolutionFacade,
|
||||
private val scope: GlobalSearchScope,
|
||||
visibilityFilter: (DeclarationDescriptor) -> Boolean,
|
||||
private val declarationTranslator: (KtDeclaration) -> KtDeclaration? = { it },
|
||||
applyExcludeSettings: Boolean = true,
|
||||
private val filterOutPrivate: Boolean = true
|
||||
) {
|
||||
@@ -94,7 +92,16 @@ class KotlinIndicesHelper(
|
||||
.filter { it.parent is KtFile && it.receiverTypeReference != null && it.hasModifier(KtTokens.OPERATOR_KEYWORD) }
|
||||
.flatMap { it.resolveToDescriptorsWithHack() }
|
||||
.filterIsInstance<FunctionDescriptor>()
|
||||
.filter { descriptorFilter(it) }
|
||||
.filter { descriptorFilter(it) && it.extensionReceiverParameter != null }
|
||||
.distinct()
|
||||
}
|
||||
|
||||
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>()
|
||||
.filter { descriptorFilter(it) && it.extensionReceiverParameter == null }
|
||||
.distinct()
|
||||
}
|
||||
|
||||
@@ -316,7 +323,8 @@ class KotlinIndicesHelper(
|
||||
return resolutionFacade.resolveImportReference(moduleDescriptor, fqName!!).filterIsInstance<CallableDescriptor>()
|
||||
}
|
||||
else {
|
||||
return (resolutionFacade.resolveToDescriptor(this) as? CallableDescriptor).singletonOrEmptyList()
|
||||
val translatedDeclaration = declarationTranslator(this) ?: return emptyList()
|
||||
return (resolutionFacade.resolveToDescriptor(translatedDeclaration) as? CallableDescriptor).singletonOrEmptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.core
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||
@@ -41,19 +42,32 @@ abstract class TypesWithOperatorDetector(
|
||||
|
||||
private val cache = HashMap<FuzzyType, Pair<FunctionDescriptor, TypeSubstitutor>?>()
|
||||
|
||||
private val extensionOperators: Collection<FunctionDescriptor> by lazy {
|
||||
val extensionOperators: Collection<FunctionDescriptor> by lazy {
|
||||
val result = ArrayList<FunctionDescriptor>()
|
||||
collectExtensionOperators(scope.collectFunctions(name, NoLookupLocation.FROM_IDE), result)
|
||||
indicesHelper?.getTopLevelExtensionOperatorsByName(name.asString())?.let { collectExtensionOperators(it, result) }
|
||||
|
||||
val extensionsFromScope = scope
|
||||
.collectFunctions(name, NoLookupLocation.FROM_IDE)
|
||||
.filter { it.extensionReceiverParameter != null }
|
||||
result.addSuitableOperators(extensionsFromScope)
|
||||
|
||||
indicesHelper?.getTopLevelExtensionOperatorsByName(name.asString())?.let { result.addSuitableOperators(it) }
|
||||
|
||||
result.distinctBy { it.original }
|
||||
}
|
||||
|
||||
private fun collectExtensionOperators(functions: Collection<FunctionDescriptor>, result: MutableCollection<FunctionDescriptor>) {
|
||||
val classesWithMemberOperators: Collection<ClassDescriptor> by lazy {
|
||||
if (indicesHelper == null) return@lazy emptyList<ClassDescriptor>()
|
||||
val operators = ArrayList<FunctionDescriptor>().addSuitableOperators(indicesHelper.getMemberOperatorsByName(name.asString()))
|
||||
operators.map { it.containingDeclaration as ClassDescriptor }.distinct()
|
||||
}
|
||||
|
||||
private fun MutableCollection<FunctionDescriptor>.addSuitableOperators(functions: Collection<FunctionDescriptor>): MutableCollection<FunctionDescriptor> {
|
||||
for (function in functions) {
|
||||
if (function.extensionReceiverParameter == null || !function.isValidOperator()) continue
|
||||
if (!function.isValidOperator()) continue
|
||||
val substitutor = checkIsSuitableByType(function, function.typeParameters) ?: continue
|
||||
result.add(function.substitute(substitutor))
|
||||
add(function.substitute(substitutor))
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun findOperator(type: FuzzyType): Pair<FunctionDescriptor, TypeSubstitutor>? {
|
||||
|
||||
Reference in New Issue
Block a user