Added better way to construct FuzzyType
This commit is contained in:
@@ -29,18 +29,11 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.typeUtil.*
|
||||
import java.util.*
|
||||
|
||||
fun CallableDescriptor.fuzzyReturnType(): FuzzyType? {
|
||||
val returnType = returnType ?: return null
|
||||
return FuzzyType(returnType, typeParameters)
|
||||
}
|
||||
fun CallableDescriptor.fuzzyReturnType() = returnType?.toFuzzyType(typeParameters)
|
||||
fun CallableDescriptor.fuzzyExtensionReceiverType() = extensionReceiverParameter?.type?.toFuzzyType(typeParameters)
|
||||
|
||||
fun CallableDescriptor.fuzzyExtensionReceiverType(): FuzzyType? {
|
||||
val receiverParameter = extensionReceiverParameter
|
||||
return if (receiverParameter != null) FuzzyType(receiverParameter.type, typeParameters) else null
|
||||
}
|
||||
|
||||
fun FuzzyType.makeNotNullable() = FuzzyType(type.makeNotNullable(), freeParameters)
|
||||
fun FuzzyType.makeNullable() = FuzzyType(type.makeNullable(), freeParameters)
|
||||
fun FuzzyType.makeNotNullable() = type.makeNotNullable().toFuzzyType(freeParameters)
|
||||
fun FuzzyType.makeNullable() = type.makeNullable().toFuzzyType(freeParameters)
|
||||
fun FuzzyType.nullability() = type.nullability()
|
||||
|
||||
fun FuzzyType.isAlmostEverything(): Boolean {
|
||||
@@ -70,6 +63,8 @@ fun FuzzyType.presentationType(): KotlinType {
|
||||
return substitutor.substitute(type, Variance.INVARIANT)!!
|
||||
}
|
||||
|
||||
fun KotlinType.toFuzzyType(freeParameters: Collection<TypeParameterDescriptor>) = FuzzyType(this, freeParameters)
|
||||
|
||||
class FuzzyType(
|
||||
val type: KotlinType,
|
||||
freeParameters: Collection<TypeParameterDescriptor>
|
||||
@@ -122,10 +117,10 @@ class FuzzyType(
|
||||
= matchedSubstitutor(otherType, MatchKind.IS_SUPERTYPE)
|
||||
|
||||
fun checkIsSubtypeOf(otherType: KotlinType): TypeSubstitutor?
|
||||
= checkIsSubtypeOf(FuzzyType(otherType, emptyList()))
|
||||
= checkIsSubtypeOf(otherType.toFuzzyType(emptyList()))
|
||||
|
||||
fun checkIsSuperTypeOf(otherType: KotlinType): TypeSubstitutor?
|
||||
= checkIsSuperTypeOf(FuzzyType(otherType, emptyList()))
|
||||
= checkIsSuperTypeOf(otherType.toFuzzyType(emptyList()))
|
||||
|
||||
private enum class MatchKind {
|
||||
IS_SUBTYPE,
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.idea.core.WhenEntryAdditionalData
|
||||
import org.jetbrains.kotlin.idea.core.fuzzyType
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.types.KotlinTypeImpl
|
||||
@@ -98,7 +98,7 @@ object KeywordValues {
|
||||
if (qualifierType != null) {
|
||||
val kClassDescriptor = resolutionFacade.getFrontendService(ReflectionTypes::class.java).kClass
|
||||
val classLiteralType = KotlinTypeImpl.create(Annotations.EMPTY, kClassDescriptor, false, listOf(TypeProjectionImpl(qualifierType)))
|
||||
val kClassTypes = listOf(FuzzyType(classLiteralType, emptyList()))
|
||||
val kClassTypes = listOf(classLiteralType.toFuzzyType(emptyList()))
|
||||
val kClassMatcher = { info: ExpectedInfo -> kClassTypes.matchExpectedInfo(info) }
|
||||
consumer.consume("class", kClassMatcher, SmartCompletionItemPriority.CLASS_LITERAL) {
|
||||
LookupElementBuilder.create(KeywordLookupObject(), "class").bold()
|
||||
@@ -110,7 +110,7 @@ object KeywordValues {
|
||||
|
||||
if (javaLangClassDescriptor != null) {
|
||||
val javaLangClassType = KotlinTypeImpl.create(Annotations.EMPTY, javaLangClassDescriptor, false, listOf(TypeProjectionImpl(qualifierType)))
|
||||
val javaClassTypes = listOf(FuzzyType(javaLangClassType, emptyList()))
|
||||
val javaClassTypes = listOf(javaLangClassType.toFuzzyType(emptyList()))
|
||||
val javaClassMatcher = { info: ExpectedInfo -> javaClassTypes.matchExpectedInfo(info) }
|
||||
consumer.consume("class", javaClassMatcher, SmartCompletionItemPriority.CLASS_LITERAL) {
|
||||
LookupElementBuilder.create(KeywordLookupObject(), "class.java")
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.idea.completion.handlers.GenerateLambdaInfo
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.lambdaPresentation
|
||||
import org.jetbrains.kotlin.idea.util.CallType
|
||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||
@@ -121,7 +121,7 @@ class LookupElementFactory(
|
||||
if (isSingleParameter) {
|
||||
//TODO: also ::function? at least for local functions
|
||||
//TODO: order for them
|
||||
val fuzzyParameterType = FuzzyType(parameterType, descriptor.typeParameters)
|
||||
val fuzzyParameterType = parameterType.toFuzzyType(descriptor.typeParameters)
|
||||
for ((variable, substitutor) in contextVariablesProvider.functionTypeVariables(fuzzyParameterType)) {
|
||||
val substitutedDescriptor = descriptor.substitute(substitutor)
|
||||
add(createFunctionCallElementWithArguments(substitutedDescriptor, variable.name.render(), useReceiverTypes))
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.idea.core.completion.PackageLookupObject
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.CallType
|
||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors
|
||||
|
||||
@@ -231,7 +232,7 @@ class SmartCompletionInBasicWeigher(
|
||||
descriptor.fuzzyTypesForSmartCompletion(smartCastCalculator, callType, resolutionFacade) to descriptor.name
|
||||
}
|
||||
|
||||
is ThisItemLookupObject -> smartCastCalculator.types(o.receiverParameter).map { FuzzyType(it, emptyList()) } to null
|
||||
is ThisItemLookupObject -> smartCastCalculator.types(o.receiverParameter).map { it.toFuzzyType(emptyList()) } to null
|
||||
|
||||
else -> return NO_MATCH_WEIGHT
|
||||
}
|
||||
|
||||
+2
-1
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||
import org.jetbrains.kotlin.idea.util.isAlmostEverything
|
||||
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -277,7 +278,7 @@ class SmartCompletion(
|
||||
if (shouldCompleteThisItems(prefixMatcher)) {
|
||||
val items = thisExpressionItems(bindingContext, place, prefixMatcher.prefix, resolutionFacade)
|
||||
for (item in items) {
|
||||
val types = smartCastCalculator.types(item.receiverParameter).map { FuzzyType(it, emptyList()) }
|
||||
val types = smartCastCalculator.types(item.receiverParameter).map { it.toFuzzyType(emptyList()) }
|
||||
val matcher = { expectedInfo: ExpectedInfo -> types.matchExpectedInfo(expectedInfo) }
|
||||
addLookupElements(null, expectedInfos, matcher) {
|
||||
item.createLookupElement().assignSmartCompletionPriority(SmartCompletionItemPriority.THIS).singletonList()
|
||||
|
||||
+4
-7
@@ -38,10 +38,7 @@ import org.jetbrains.kotlin.idea.core.Tail
|
||||
import org.jetbrains.kotlin.idea.core.multipleFuzzyTypes
|
||||
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.makeNotNullable
|
||||
import org.jetbrains.kotlin.idea.util.presentationType
|
||||
import org.jetbrains.kotlin.idea.util.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
@@ -316,7 +313,7 @@ class TypeInstantiationItems(
|
||||
|
||||
private val baseHasTypeArgs = classDescriptor.declaredTypeParameters.isNotEmpty()
|
||||
private val expectedType = KotlinTypeImpl.create(Annotations.EMPTY, classDescriptor, false, typeArgs)
|
||||
private val expectedFuzzyType = FuzzyType(expectedType, freeParameters)
|
||||
private val expectedFuzzyType = expectedType.toFuzzyType(freeParameters)
|
||||
|
||||
override fun search(nameFilter: (String) -> Boolean, consumer: (LookupElement) -> Unit) {
|
||||
val parameters = ClassInheritorsSearch.SearchParameters(psiClass, inheritorSearchScope, true, true, false, nameFilter)
|
||||
@@ -327,13 +324,13 @@ class TypeInstantiationItems(
|
||||
) ?: continue
|
||||
if (!visibilityFilter(descriptor)) continue
|
||||
|
||||
var inheritorFuzzyType = FuzzyType(descriptor.defaultType, descriptor.typeConstructor.parameters)
|
||||
var inheritorFuzzyType = descriptor.defaultType.toFuzzyType(descriptor.typeConstructor.parameters)
|
||||
val hasTypeArgs = descriptor.declaredTypeParameters.isNotEmpty()
|
||||
if (hasTypeArgs || baseHasTypeArgs) {
|
||||
val substitutor = inheritorFuzzyType.checkIsSubtypeOf(expectedFuzzyType) ?: continue
|
||||
if (!substitutor.isEmpty) {
|
||||
val inheritorTypeSubstituted = substitutor.substitute(inheritorFuzzyType.type, Variance.INVARIANT)!!
|
||||
inheritorFuzzyType = FuzzyType(inheritorTypeSubstituted, freeParameters + inheritorFuzzyType.freeParameters)
|
||||
inheritorFuzzyType = inheritorTypeSubstituted.toFuzzyType(freeParameters + inheritorFuzzyType.freeParameters)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -248,8 +248,7 @@ private fun MutableCollection<LookupElement>.addLookupElementsForNullable(factor
|
||||
|
||||
fun CallableDescriptor.callableReferenceType(resolutionFacade: ResolutionFacade): FuzzyType? {
|
||||
if (!CallType.CALLABLE_REFERENCE.descriptorKindFilter.accepts(this)) return null // not supported by callable references
|
||||
val type = getReflectionTypeForCandidateDescriptor(this, resolutionFacade.getFrontendService(ReflectionTypes::class.java)) ?: return null
|
||||
return FuzzyType(type, emptyList())
|
||||
return getReflectionTypeForCandidateDescriptor(this, resolutionFacade.getFrontendService(ReflectionTypes::class.java))?.toFuzzyType(emptyList())
|
||||
}
|
||||
|
||||
enum class SmartCompletionItemPriority {
|
||||
@@ -294,14 +293,14 @@ fun DeclarationDescriptor.fuzzyTypesForSmartCompletion(
|
||||
if (returnType.type.isNothing() || returnType.isAlmostEverything()) return emptyList()
|
||||
|
||||
if (this is VariableDescriptor) { //TODO: generic properties!
|
||||
return smartCastCalculator.types(this).map { FuzzyType(it, emptyList()) }
|
||||
return smartCastCalculator.types(this).map { it.toFuzzyType(emptyList()) }
|
||||
}
|
||||
else {
|
||||
return listOf(returnType)
|
||||
}
|
||||
}
|
||||
else if (this is ClassDescriptor && kind.isSingleton) {
|
||||
return listOf(FuzzyType(defaultType, emptyList()))
|
||||
return listOf(defaultType.toFuzzyType(emptyList()))
|
||||
}
|
||||
else {
|
||||
return emptyList()
|
||||
|
||||
@@ -100,15 +100,15 @@ class ExpectedInfo(
|
||||
: this(ByExpectedTypeFilter(fuzzyType), expectedName, tail, itemOptions, additionalData)
|
||||
|
||||
constructor(type: KotlinType, expectedName: String?, tail: Tail?, itemOptions: ItemOptions = ItemOptions.DEFAULT, additionalData: ExpectedInfo.AdditionalData? = null)
|
||||
: this(FuzzyType(type, emptyList()), expectedName, tail, itemOptions, additionalData)
|
||||
: this(type.toFuzzyType(emptyList()), expectedName, tail, itemOptions, additionalData)
|
||||
|
||||
fun matchingSubstitutor(descriptorType: FuzzyType): TypeSubstitutor? = filter.matchingSubstitutor(descriptorType)
|
||||
|
||||
fun matchingSubstitutor(descriptorType: KotlinType): TypeSubstitutor? = matchingSubstitutor(FuzzyType(descriptorType, emptyList()))
|
||||
fun matchingSubstitutor(descriptorType: KotlinType): TypeSubstitutor? = matchingSubstitutor(descriptorType.toFuzzyType(emptyList()))
|
||||
|
||||
companion object {
|
||||
fun createForArgument(type: KotlinType, expectedName: String?, tail: Tail?, argumentData: ArgumentPositionData, itemOptions: ItemOptions = ItemOptions.DEFAULT): ExpectedInfo {
|
||||
return ExpectedInfo(FuzzyType(type, argumentData.function.typeParameters), expectedName, tail, itemOptions, argumentData)
|
||||
return ExpectedInfo(type.toFuzzyType(argumentData.function.typeParameters), expectedName, tail, itemOptions, argumentData)
|
||||
}
|
||||
|
||||
fun createForNamedArgumentExpected(argumentData: ArgumentPositionData): ExpectedInfo {
|
||||
@@ -116,7 +116,7 @@ class ExpectedInfo(
|
||||
}
|
||||
|
||||
fun createForReturnValue(type: KotlinType?, callable: CallableDescriptor): ExpectedInfo {
|
||||
val filter = if (type != null) ByExpectedTypeFilter(FuzzyType(type, emptyList())) else ByTypeFilter.All
|
||||
val filter = if (type != null) ByExpectedTypeFilter(type.toFuzzyType(emptyList())) else ByTypeFilter.All
|
||||
return ExpectedInfo(filter, callable.name.asString(), null, additionalData = ReturnValueAdditionalData(callable))
|
||||
}
|
||||
}
|
||||
@@ -494,7 +494,7 @@ class ExpectedInfos(
|
||||
.filter { it.type.isFunctionType }
|
||||
.map {
|
||||
val returnType = getReturnTypeFromFunctionType(it.type)
|
||||
ExpectedInfo(FuzzyType(returnType, it.freeParameters), null, Tail.RBRACE)
|
||||
ExpectedInfo(returnType.toFuzzyType(it.freeParameters), null, Tail.RBRACE)
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -611,8 +611,8 @@ class ExpectedInfos(
|
||||
|
||||
val scope = expressionWithType.getResolutionScope(bindingContext, resolutionFacade)
|
||||
val propertyOwnerType = property.fuzzyExtensionReceiverType()
|
||||
?: property.dispatchReceiverParameter?.type?.let { FuzzyType(it, emptyList()) }
|
||||
?: FuzzyType(property.builtIns.nullableNothingType, emptyList())
|
||||
?: property.dispatchReceiverParameter?.type?.toFuzzyType(emptyList())
|
||||
?: property.builtIns.nullableNothingType.toFuzzyType(emptyList())
|
||||
|
||||
val explicitPropertyType = property.fuzzyReturnType()?.check { propertyDeclaration.typeReference != null }
|
||||
val typesWithGetDetector = TypesWithGetValueDetector(scope, indicesHelper, propertyOwnerType, explicitPropertyType)
|
||||
@@ -624,11 +624,11 @@ class ExpectedInfos(
|
||||
|
||||
if (typesWithSetDetector == null) return getOperatorSubstitutor
|
||||
|
||||
val substitutedType = FuzzyType(getOperatorSubstitutor.substitute(descriptorType.type, Variance.INVARIANT)!!, descriptorType.freeParameters)
|
||||
val substitutedType = getOperatorSubstitutor.substitute(descriptorType.type, Variance.INVARIANT)!!.toFuzzyType(descriptorType.freeParameters)
|
||||
|
||||
val (setValueOperator, setOperatorSubstitutor) = typesWithSetDetector.findOperator(substitutedType) ?: return null
|
||||
val propertyType = explicitPropertyType ?: getValueOperator.fuzzyReturnType()!!
|
||||
val setParamType = FuzzyType(setValueOperator.valueParameters.last().type, setValueOperator.typeParameters)
|
||||
val setParamType = setValueOperator.valueParameters.last().type.toFuzzyType(setValueOperator.typeParameters)
|
||||
val setParamTypeSubstitutor = setParamType.checkIsSuperTypeOf(propertyType) ?: return null
|
||||
return getOperatorSubstitutor
|
||||
.combineIfNoConflicts(setOperatorSubstitutor, descriptorType.freeParameters)
|
||||
@@ -641,14 +641,14 @@ class ExpectedInfos(
|
||||
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))
|
||||
val substitutor = matchingSubstitutor(type.toFuzzyType(typeParameters)) ?: continue
|
||||
result.add(substitutor.substitute(type, Variance.INVARIANT)!!.toFuzzyType(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.add(substitutor.substitute(receiverType.type, Variance.INVARIANT)!!.toFuzzyType(receiverType.freeParameters))
|
||||
}
|
||||
|
||||
result
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.core
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
@@ -60,14 +61,14 @@ class IterableTypesDetection(
|
||||
}
|
||||
|
||||
override fun isIterable(type: KotlinType, loopVarType: KotlinType?): Boolean
|
||||
= isIterable(FuzzyType(type, emptyList()), loopVarType)
|
||||
= isIterable(type.toFuzzyType(emptyList()), loopVarType)
|
||||
|
||||
private fun elementType(type: FuzzyType): FuzzyType? {
|
||||
return cache.getOrPutNullable(type, { elementTypeNoCache(type) })
|
||||
}
|
||||
|
||||
override fun elementType(type: KotlinType): FuzzyType?
|
||||
= elementType(FuzzyType(type, emptyList()))
|
||||
= elementType(type.toFuzzyType(emptyList()))
|
||||
|
||||
private fun elementTypeNoCache(type: FuzzyType): FuzzyType? {
|
||||
// optimization
|
||||
@@ -77,14 +78,14 @@ class IterableTypesDetection(
|
||||
val context = ExpressionTypingContext.newContext(BindingTraceContext(), scope, DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE)
|
||||
val expressionReceiver = ExpressionReceiver.create(expression, type.type, context.trace.bindingContext)
|
||||
val elementType = forLoopConventionsChecker.checkIterableConvention(expressionReceiver, context)
|
||||
return elementType?.let { FuzzyType(it, type.freeParameters) }
|
||||
return elementType?.let { it.toFuzzyType(type.freeParameters) }
|
||||
}
|
||||
|
||||
private fun canBeIterable(type: FuzzyType): Boolean {
|
||||
return type.type.memberScope.getContributedFunctions(iteratorName, NoLookupLocation.FROM_IDE).isNotEmpty() ||
|
||||
typesWithExtensionIterator.any {
|
||||
val freeParams = it.arguments.mapNotNull { it.type.constructor.declarationDescriptor as? TypeParameterDescriptor }
|
||||
type.checkIsSubtypeOf(FuzzyType(it, freeParams)) != null
|
||||
type.checkIsSubtypeOf(it.toFuzzyType(freeParams)) != null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,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
|
||||
import org.jetbrains.kotlin.idea.util.combineIfNoConflicts
|
||||
import org.jetbrains.kotlin.idea.util.fuzzyExtensionReceiverType
|
||||
import org.jetbrains.kotlin.idea.util.nullability
|
||||
import org.jetbrains.kotlin.idea.util.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
@@ -119,7 +116,7 @@ class TypesWithContainsDetector(
|
||||
|
||||
override fun checkIsSuitableByType(operator: FunctionDescriptor, freeTypeParams: Collection<TypeParameterDescriptor>): TypeSubstitutor? {
|
||||
val parameter = operator.valueParameters.single()
|
||||
val fuzzyParameterType = FuzzyType(parameter.type, operator.typeParameters + freeTypeParams)
|
||||
val fuzzyParameterType = parameter.type.toFuzzyType(operator.typeParameters + freeTypeParams)
|
||||
return fuzzyParameterType.checkIsSuperTypeOf(argumentType)
|
||||
}
|
||||
}
|
||||
@@ -132,12 +129,12 @@ class TypesWithGetValueDetector(
|
||||
) : TypesWithOperatorDetector(OperatorNameConventions.GET_VALUE, scope, indicesHelper) {
|
||||
|
||||
override fun checkIsSuitableByType(operator: FunctionDescriptor, freeTypeParams: Collection<TypeParameterDescriptor>): TypeSubstitutor? {
|
||||
val paramType = FuzzyType(operator.valueParameters.first().type, freeTypeParams)
|
||||
val paramType = operator.valueParameters.first().type.toFuzzyType(freeTypeParams)
|
||||
val substitutor = paramType.checkIsSuperTypeOf(propertyOwnerType) ?: return null
|
||||
|
||||
if (propertyType == null) return substitutor
|
||||
|
||||
val fuzzyReturnType = FuzzyType(operator.returnType ?: return null, freeTypeParams)
|
||||
val fuzzyReturnType = operator.returnType?.toFuzzyType(freeTypeParams) ?: return null
|
||||
val substitutorFromPropertyType = fuzzyReturnType.checkIsSubtypeOf(propertyType) ?: return null
|
||||
return substitutor.combineIfNoConflicts(substitutorFromPropertyType, freeTypeParams)
|
||||
}
|
||||
@@ -150,7 +147,7 @@ class TypesWithSetValueDetector(
|
||||
) : TypesWithOperatorDetector(OperatorNameConventions.SET_VALUE, scope, indicesHelper) {
|
||||
|
||||
override fun checkIsSuitableByType(operator: FunctionDescriptor, freeTypeParams: Collection<TypeParameterDescriptor>): TypeSubstitutor? {
|
||||
val paramType = FuzzyType(operator.valueParameters.first().type, freeTypeParams)
|
||||
val paramType = operator.valueParameters.first().type.toFuzzyType(freeTypeParams)
|
||||
return paramType.checkIsSuperTypeOf(propertyOwnerType)
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.idea.core.ExpectedInfo
|
||||
import org.jetbrains.kotlin.idea.core.ExpectedInfos
|
||||
import org.jetbrains.kotlin.idea.core.SmartCastCalculator
|
||||
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -55,6 +55,6 @@ class SuitableVariableMacro : BaseKotlinVariableMacro<SuitableVariableMacro.Stat
|
||||
override fun isSuitable(variableDescriptor: VariableDescriptor, project: Project, state: State?): Boolean {
|
||||
if (state == null) return true
|
||||
val types = state.smartCastCalculator.types(variableDescriptor)
|
||||
return state.expectedInfos.any { expectedInfo -> types.any { expectedInfo.filter.matchingSubstitutor(FuzzyType(it, emptyList())) != null } }
|
||||
return state.expectedInfos.any { expectedInfo -> types.any { expectedInfo.filter.matchingSubstitutor(it.toFuzzyType(emptyList())) != null } }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user