Checking return value supported in OverridingUtil

This commit is contained in:
Andrey Breslav
2014-05-30 16:05:59 +04:00
parent e50a17e668
commit 3f151a022e
@@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import java.util.*; import java.util.*;
import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.CONFLICT; import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.CONFLICT;
import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.INCOMPATIBLE;
import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE; import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
public class OverridingUtil { public class OverridingUtil {
@@ -80,13 +81,18 @@ public class OverridingUtil {
return OverrideCompatibilityInfo.nameMismatch(); return OverrideCompatibilityInfo.nameMismatch();
} }
return isOverridableByImpl(superDescriptor, subDescriptor, true); return isOverridableByImpl(superDescriptor, subDescriptor, true, false);
} }
/** /**
* @param forOverride true for override, false for overload * @param forOverride true for override, false for overload
*/ */
OverrideCompatibilityInfo isOverridableByImpl(@NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor, boolean forOverride) { OverrideCompatibilityInfo isOverridableByImpl(
@NotNull CallableDescriptor superDescriptor,
@NotNull CallableDescriptor subDescriptor,
boolean forOverride,
boolean checkReturnType
) {
// TODO : Visibility // TODO : Visibility
@@ -142,7 +148,7 @@ public class OverridingUtil {
TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i); TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i);
TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i); TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i);
if (!JetTypeChecker.INSTANCE.equalTypes(superTypeParameter.getUpperBoundsAsType(), subTypeParameter.getUpperBoundsAsType(), localEqualityAxioms)) { if (!areTypesEquivalent(superTypeParameter.getUpperBoundsAsType(), subTypeParameter.getUpperBoundsAsType(), localEqualityAxioms)) {
return OverrideCompatibilityInfo.boundsMismatch(superTypeParameter, subTypeParameter); return OverrideCompatibilityInfo.boundsMismatch(superTypeParameter, subTypeParameter);
} }
} }
@@ -151,12 +157,23 @@ public class OverridingUtil {
JetType superValueParameter = superValueParameters.get(i); JetType superValueParameter = superValueParameters.get(i);
JetType subValueParameter = subValueParameters.get(i); JetType subValueParameter = subValueParameters.get(i);
boolean bothErrors = superValueParameter.isError() && subValueParameter.isError(); if (!areTypesEquivalent(superValueParameter, subValueParameter, localEqualityAxioms)) {
if (!bothErrors && !JetTypeChecker.INSTANCE.equalTypes(superValueParameter, subValueParameter, localEqualityAxioms)) { return OverrideCompatibilityInfo.valueParameterTypeMismatch(superValueParameter, subValueParameter, INCOMPATIBLE);
return OverrideCompatibilityInfo.valueParameterTypeMismatch(superValueParameter, subValueParameter, OverrideCompatibilityInfo.Result.INCOMPATIBLE);
} }
} }
if (checkReturnType) {
JetType superReturnType = superDescriptor.getReturnType();
JetType subReturnType = subDescriptor.getReturnType();
if (superReturnType != null &&
subReturnType != null &&
!areTypesEquivalent(superReturnType, subReturnType, localEqualityAxioms)) {
return OverrideCompatibilityInfo.returnTypeMismatch(superReturnType, subReturnType);
}
}
for (ExternalOverridabilityCondition externalCondition : EXTERNAL_CONDITIONS) { for (ExternalOverridabilityCondition externalCondition : EXTERNAL_CONDITIONS) {
if (!externalCondition.isOverridable(superDescriptor, subDescriptor)) { if (!externalCondition.isOverridable(superDescriptor, subDescriptor)) {
return OverrideCompatibilityInfo.externalConditionFailed(externalCondition.getClass()); return OverrideCompatibilityInfo.externalConditionFailed(externalCondition.getClass());
@@ -170,7 +187,7 @@ public class OverridingUtil {
JetType subValueParameterType = getUpperBound(subValueParameters.get(i)); JetType subValueParameterType = getUpperBound(subValueParameters.get(i));
// TODO: compare erasure // TODO: compare erasure
if (!JetTypeChecker.INSTANCE.equalTypes(superValueParameterType, subValueParameterType)) { if (!JetTypeChecker.INSTANCE.equalTypes(superValueParameterType, subValueParameterType)) {
return OverrideCompatibilityInfo.valueParameterTypeMismatch(superValueParameterType, subValueParameterType, OverrideCompatibilityInfo.Result.INCOMPATIBLE); return OverrideCompatibilityInfo.valueParameterTypeMismatch(superValueParameterType, subValueParameterType, INCOMPATIBLE);
} }
} }
@@ -183,6 +200,18 @@ public class OverridingUtil {
return OverrideCompatibilityInfo.success(); return OverrideCompatibilityInfo.success();
} }
private static boolean areTypesEquivalent(
@NotNull JetType typeInSuper,
@NotNull JetType typeInSub,
@NotNull JetTypeChecker.TypeConstructorEquality axioms
) {
boolean bothErrors = typeInSuper.isError() && typeInSub.isError();
if (!bothErrors && !JetTypeChecker.INSTANCE.equalTypes(typeInSuper, typeInSub, axioms)) {
return false;
}
return true;
}
private static List<JetType> compiledValueParameters(CallableDescriptor callableDescriptor) { private static List<JetType> compiledValueParameters(CallableDescriptor callableDescriptor) {
ReceiverParameterDescriptor receiverParameter = callableDescriptor.getReceiverParameter(); ReceiverParameterDescriptor receiverParameter = callableDescriptor.getReceiverParameter();
ArrayList<JetType> parameters = new ArrayList<JetType>(); ArrayList<JetType> parameters = new ArrayList<JetType>();
@@ -510,27 +539,27 @@ public class OverridingUtil {
@NotNull @NotNull
public static OverrideCompatibilityInfo nameMismatch() { public static OverrideCompatibilityInfo nameMismatch() {
return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "nameMismatch"); // TODO return new OverrideCompatibilityInfo(INCOMPATIBLE, "nameMismatch"); // TODO
} }
@NotNull @NotNull
public static OverrideCompatibilityInfo typeParameterNumberMismatch() { public static OverrideCompatibilityInfo typeParameterNumberMismatch() {
return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "typeParameterNumberMismatch"); // TODO return new OverrideCompatibilityInfo(INCOMPATIBLE, "typeParameterNumberMismatch"); // TODO
} }
@NotNull @NotNull
public static OverrideCompatibilityInfo receiverPresenceMismatch() { public static OverrideCompatibilityInfo receiverPresenceMismatch() {
return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "receiverPresenceMismatch"); // TODO return new OverrideCompatibilityInfo(INCOMPATIBLE, "receiverPresenceMismatch"); // TODO
} }
@NotNull @NotNull
public static OverrideCompatibilityInfo valueParameterNumberMismatch() { public static OverrideCompatibilityInfo valueParameterNumberMismatch() {
return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "valueParameterNumberMismatch"); // TODO return new OverrideCompatibilityInfo(INCOMPATIBLE, "valueParameterNumberMismatch"); // TODO
} }
@NotNull @NotNull
public static OverrideCompatibilityInfo boundsMismatch(TypeParameterDescriptor superTypeParameter, TypeParameterDescriptor subTypeParameter) { public static OverrideCompatibilityInfo boundsMismatch(TypeParameterDescriptor superTypeParameter, TypeParameterDescriptor subTypeParameter) {
return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "boundsMismatch"); // TODO return new OverrideCompatibilityInfo(INCOMPATIBLE, "boundsMismatch"); // TODO
} }
@NotNull @NotNull
@@ -540,7 +569,7 @@ public class OverridingUtil {
@NotNull @NotNull
public static OverrideCompatibilityInfo memberKindMismatch() { public static OverrideCompatibilityInfo memberKindMismatch() {
return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "memberKindMismatch"); // TODO return new OverrideCompatibilityInfo(INCOMPATIBLE, "memberKindMismatch"); // TODO
} }
@NotNull @NotNull
@@ -550,12 +579,12 @@ public class OverridingUtil {
@NotNull @NotNull
public static OverrideCompatibilityInfo varOverriddenByVal() { public static OverrideCompatibilityInfo varOverriddenByVal() {
return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "varOverriddenByVal"); // TODO return new OverrideCompatibilityInfo(INCOMPATIBLE, "varOverriddenByVal"); // TODO
} }
@NotNull @NotNull
public static OverrideCompatibilityInfo externalConditionFailed(Class<? extends ExternalOverridabilityCondition> conditionClass) { public static OverrideCompatibilityInfo externalConditionFailed(Class<? extends ExternalOverridabilityCondition> conditionClass) {
return new OverrideCompatibilityInfo(Result.INCOMPATIBLE, "externalConditionFailed: " + conditionClass.getName()); // TODO return new OverrideCompatibilityInfo(INCOMPATIBLE, "externalConditionFailed: " + conditionClass.getName()); // TODO
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////