Smart completion works for cases when no exact type known (generic parameter substitution is not known)
This commit is contained in:
@@ -78,20 +78,26 @@ class FuzzyType(
|
||||
}
|
||||
}
|
||||
|
||||
public fun checkIsSubtypeOf(otherType: JetType): TypeSubstitutor?
|
||||
public fun checkIsSubtypeOf(otherType: FuzzyType): TypeSubstitutor?
|
||||
= matchedSubstitutor(otherType, MatchKind.IS_SUBTYPE)
|
||||
|
||||
public fun checkIsSuperTypeOf(otherType: JetType): TypeSubstitutor?
|
||||
public fun checkIsSuperTypeOf(otherType: FuzzyType): TypeSubstitutor?
|
||||
= matchedSubstitutor(otherType, MatchKind.IS_SUPERTYPE)
|
||||
|
||||
public fun checkIsSubtypeOf(otherType: JetType): TypeSubstitutor?
|
||||
= checkIsSubtypeOf(FuzzyType(otherType, emptyList()))
|
||||
|
||||
public fun checkIsSuperTypeOf(otherType: JetType): TypeSubstitutor?
|
||||
= checkIsSuperTypeOf(FuzzyType(otherType, emptyList()))
|
||||
|
||||
private enum class MatchKind {
|
||||
IS_SUBTYPE,
|
||||
IS_SUPERTYPE
|
||||
}
|
||||
|
||||
private fun matchedSubstitutor(otherType: JetType, matchKind: MatchKind): TypeSubstitutor? {
|
||||
private fun matchedSubstitutor(otherType: FuzzyType, matchKind: MatchKind): TypeSubstitutor? {
|
||||
if (type.isError()) return null
|
||||
if (otherType.isError()) return null
|
||||
if (otherType.type.isError()) return null
|
||||
|
||||
fun JetType.checkInheritance(otherType: JetType): Boolean {
|
||||
return when (matchKind) {
|
||||
@@ -100,16 +106,17 @@ class FuzzyType(
|
||||
}
|
||||
}
|
||||
|
||||
if (freeParameters.isEmpty()) {
|
||||
return if (type.checkInheritance(otherType)) TypeSubstitutor.EMPTY else null
|
||||
if (freeParameters.isEmpty() && otherType.freeParameters.isEmpty()) {
|
||||
return if (type.checkInheritance(otherType.type)) TypeSubstitutor.EMPTY else null
|
||||
}
|
||||
|
||||
val constraintSystem = ConstraintSystemImpl()
|
||||
constraintSystem.registerTypeVariables(freeParameters, { Variance.INVARIANT })
|
||||
constraintSystem.registerTypeVariables(otherType.freeParameters, { Variance.INVARIANT })
|
||||
|
||||
when (matchKind) {
|
||||
MatchKind.IS_SUBTYPE -> constraintSystem.addSubtypeConstraint(type, otherType, ConstraintPositionKind.RECEIVER_POSITION.position())
|
||||
MatchKind.IS_SUPERTYPE -> constraintSystem.addSubtypeConstraint(otherType, type, ConstraintPositionKind.RECEIVER_POSITION.position())
|
||||
MatchKind.IS_SUBTYPE -> constraintSystem.addSubtypeConstraint(type, otherType.type, ConstraintPositionKind.RECEIVER_POSITION.position())
|
||||
MatchKind.IS_SUPERTYPE -> constraintSystem.addSubtypeConstraint(otherType.type, type, ConstraintPositionKind.RECEIVER_POSITION.position())
|
||||
}
|
||||
|
||||
constraintSystem.fixVariables()
|
||||
@@ -119,7 +126,11 @@ class FuzzyType(
|
||||
// that's why we have to check subtyping manually
|
||||
val substitutor = constraintSystem.getResultingSubstitutor()
|
||||
val substitutedType = substitutor.substitute(type, Variance.INVARIANT)
|
||||
return if (substitutedType != null && substitutedType.checkInheritance(otherType)) substitutor else null
|
||||
val otherSubstitutedType = substitutor.substitute(otherType.type, Variance.INVARIANT)
|
||||
return if (substitutedType != null && otherSubstitutedType != null && substitutedType.checkInheritance(otherSubstitutedType))
|
||||
substitutor
|
||||
else
|
||||
null
|
||||
}
|
||||
else {
|
||||
return null
|
||||
|
||||
Reference in New Issue
Block a user