Unify code for checking return type on override for fun/property

This fixes issues with the refinement of property' return type because
for functions' return type we already perform refinement properly
This commit is contained in:
Dmitry Savvinov
2020-09-27 21:23:46 +03:00
parent 736ecf3e9f
commit ac63d8b3bf
2 changed files with 20 additions and 39 deletions
@@ -795,19 +795,13 @@ class OverrideResolver(
) {
if (overriddenDescriptors.size <= 1) return
val propertyDescriptor = descriptor as? PropertyDescriptor
for (overriddenDescriptor in overriddenDescriptors) {
if (propertyDescriptor != null) {
val overriddenPropertyDescriptor =
overriddenDescriptor.assertedCast<PropertyDescriptor> { "$overriddenDescriptor is not a property" }
if (!isPropertyTypeOkForOverride(overriddenPropertyDescriptor, propertyDescriptor)) {
reportingStrategy.typeMismatchOnInheritance(propertyDescriptor, overriddenPropertyDescriptor)
}
} else {
if (!isReturnTypeOkForOverride(overriddenDescriptor, descriptor, kotlinTypeRefiner)) {
reportingStrategy.typeMismatchOnInheritance(descriptor, overriddenDescriptor)
}
require(descriptor !is PropertyDescriptor || overriddenDescriptor is PropertyDescriptor) {
"$overriddenDescriptor is not a property"
}
if (!isReturnTypeOkForOverride(overriddenDescriptor, descriptor, kotlinTypeRefiner)) {
reportingStrategy.typeMismatchOnInheritance(descriptor, overriddenDescriptor)
}
}
}
@@ -852,15 +846,13 @@ class OverrideResolver(
reportError.overridingFinalMember(memberDescriptor, overridden)
}
if (propertyMemberDescriptor != null) {
val overriddenProperty = overridden.assertedCast<PropertyDescriptor> {
"$overridden is overridden by property $propertyMemberDescriptor"
if (!isReturnTypeOkForOverride(overridden, memberDescriptor, kotlinTypeRefiner)) {
if (memberDescriptor is PropertyDescriptor) {
require(overridden is PropertyDescriptor) { "$overridden is overridden by property $propertyMemberDescriptor" }
reportError.propertyTypeMismatchOnOverride(memberDescriptor, overridden)
} else {
reportError.returnTypeMismatchOnOverride(memberDescriptor, overridden)
}
if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor, kotlinTypeRefiner)) {
reportError.propertyTypeMismatchOnOverride(propertyMemberDescriptor, overriddenProperty)
}
} else if (!isReturnTypeOkForOverride(overridden, memberDescriptor, kotlinTypeRefiner)) {
reportError.returnTypeMismatchOnOverride(memberDescriptor, overridden)
}
if (checkPropertyKind(overridden, true) && checkPropertyKind(memberDescriptor, false)) {
@@ -872,7 +864,7 @@ class OverrideResolver(
private fun isReturnTypeOkForOverride(
superDescriptor: CallableDescriptor,
subDescriptor: CallableDescriptor,
kotlinTypeRefiner: KotlinTypeRefiner
kotlinTypeRefiner: KotlinTypeRefiner,
): Boolean {
val typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor) ?: return false
@@ -882,7 +874,11 @@ class OverrideResolver(
val substitutedSuperReturnType = typeSubstitutor.substitute(superReturnType, Variance.OUT_VARIANCE)!!
return NewKotlinTypeCheckerImpl(kotlinTypeRefiner).isSubtypeOf(subReturnType, substitutedSuperReturnType)
val typeChecker = NewKotlinTypeCheckerImpl(kotlinTypeRefiner)
return if (superDescriptor is PropertyDescriptor && superDescriptor.isVar)
typeChecker.equalTypes(subReturnType, substitutedSuperReturnType)
else
typeChecker.isSubtypeOf(subReturnType, substitutedSuperReturnType)
}
private fun prepareTypeSubstitutor(
@@ -901,21 +897,6 @@ class OverrideResolver(
return IndexedParametersSubstitution(superTypeParameters, arguments).buildSubstitutor()
}
private fun isPropertyTypeOkForOverride(
superDescriptor: PropertyDescriptor,
subDescriptor: PropertyDescriptor
): Boolean {
val typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor) ?: return false
val substitutedSuperReturnType = typeSubstitutor.substitute(superDescriptor.type, Variance.OUT_VARIANCE)!!
return if (superDescriptor.isVar) {
KotlinTypeChecker.DEFAULT.equalTypes(subDescriptor.type, substitutedSuperReturnType)
} else {
KotlinTypeChecker.DEFAULT.isSubtypeOf(subDescriptor.type, substitutedSuperReturnType)
}
}
private fun findDataModifierForDataClass(dataClass: DeclarationDescriptor): PsiElement {
val classDeclaration = DescriptorToSourceUtils.getSourceFromDescriptor(dataClass) as KtClassOrObject?
if (classDeclaration?.modifierList != null) {
+2 -2
View File
@@ -7,7 +7,7 @@ interface Derived : Base {
override fun Expect.expectInReceiver()
override val expectVal: <!PROPERTY_TYPE_MISMATCH_ON_OVERRIDE!>Expect<!>
override val expectVal: Expect
override var expectVar: <!VAR_TYPE_MISMATCH_ON_OVERRIDE!>Expect<!>
override var expectVar: Expect
}