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:
@@ -795,19 +795,13 @@ class OverrideResolver(
|
|||||||
) {
|
) {
|
||||||
if (overriddenDescriptors.size <= 1) return
|
if (overriddenDescriptors.size <= 1) return
|
||||||
|
|
||||||
val propertyDescriptor = descriptor as? PropertyDescriptor
|
|
||||||
|
|
||||||
for (overriddenDescriptor in overriddenDescriptors) {
|
for (overriddenDescriptor in overriddenDescriptors) {
|
||||||
if (propertyDescriptor != null) {
|
require(descriptor !is PropertyDescriptor || overriddenDescriptor is PropertyDescriptor) {
|
||||||
val overriddenPropertyDescriptor =
|
"$overriddenDescriptor is not a property"
|
||||||
overriddenDescriptor.assertedCast<PropertyDescriptor> { "$overriddenDescriptor is not a property" }
|
}
|
||||||
if (!isPropertyTypeOkForOverride(overriddenPropertyDescriptor, propertyDescriptor)) {
|
|
||||||
reportingStrategy.typeMismatchOnInheritance(propertyDescriptor, overriddenPropertyDescriptor)
|
if (!isReturnTypeOkForOverride(overriddenDescriptor, descriptor, kotlinTypeRefiner)) {
|
||||||
}
|
reportingStrategy.typeMismatchOnInheritance(descriptor, overriddenDescriptor)
|
||||||
} else {
|
|
||||||
if (!isReturnTypeOkForOverride(overriddenDescriptor, descriptor, kotlinTypeRefiner)) {
|
|
||||||
reportingStrategy.typeMismatchOnInheritance(descriptor, overriddenDescriptor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -852,15 +846,13 @@ class OverrideResolver(
|
|||||||
reportError.overridingFinalMember(memberDescriptor, overridden)
|
reportError.overridingFinalMember(memberDescriptor, overridden)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propertyMemberDescriptor != null) {
|
if (!isReturnTypeOkForOverride(overridden, memberDescriptor, kotlinTypeRefiner)) {
|
||||||
val overriddenProperty = overridden.assertedCast<PropertyDescriptor> {
|
if (memberDescriptor is PropertyDescriptor) {
|
||||||
"$overridden is overridden by property $propertyMemberDescriptor"
|
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)) {
|
if (checkPropertyKind(overridden, true) && checkPropertyKind(memberDescriptor, false)) {
|
||||||
@@ -872,7 +864,7 @@ class OverrideResolver(
|
|||||||
private fun isReturnTypeOkForOverride(
|
private fun isReturnTypeOkForOverride(
|
||||||
superDescriptor: CallableDescriptor,
|
superDescriptor: CallableDescriptor,
|
||||||
subDescriptor: CallableDescriptor,
|
subDescriptor: CallableDescriptor,
|
||||||
kotlinTypeRefiner: KotlinTypeRefiner
|
kotlinTypeRefiner: KotlinTypeRefiner,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor) ?: return false
|
val typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor) ?: return false
|
||||||
|
|
||||||
@@ -882,7 +874,11 @@ class OverrideResolver(
|
|||||||
|
|
||||||
val substitutedSuperReturnType = typeSubstitutor.substitute(superReturnType, Variance.OUT_VARIANCE)!!
|
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(
|
private fun prepareTypeSubstitutor(
|
||||||
@@ -901,21 +897,6 @@ class OverrideResolver(
|
|||||||
return IndexedParametersSubstitution(superTypeParameters, arguments).buildSubstitutor()
|
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 {
|
private fun findDataModifierForDataClass(dataClass: DeclarationDescriptor): PsiElement {
|
||||||
val classDeclaration = DescriptorToSourceUtils.getSourceFromDescriptor(dataClass) as KtClassOrObject?
|
val classDeclaration = DescriptorToSourceUtils.getSourceFromDescriptor(dataClass) as KtClassOrObject?
|
||||||
if (classDeclaration?.modifierList != null) {
|
if (classDeclaration?.modifierList != null) {
|
||||||
|
|||||||
+2
-2
@@ -7,7 +7,7 @@ interface Derived : Base {
|
|||||||
|
|
||||||
override fun Expect.expectInReceiver()
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user