Equality moved to type checker
This commit is contained in:
@@ -153,7 +153,7 @@ public class OverridingUtil {
|
||||
TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i);
|
||||
TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i);
|
||||
|
||||
if (!JetTypeImpl.equalTypes(superTypeParameter.getUpperBoundsAsType(), subTypeParameter.getUpperBoundsAsType(), axioms)) {
|
||||
if (!JetTypeChecker.INSTANCE.equalTypes(superTypeParameter.getUpperBoundsAsType(), subTypeParameter.getUpperBoundsAsType(), axioms)) {
|
||||
return OverrideCompatibilityInfo.boundsMismatch(superTypeParameter, subTypeParameter);
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ public class OverridingUtil {
|
||||
JetType superValueParameter = superValueParameters.get(i);
|
||||
JetType subValueParameter = subValueParameters.get(i);
|
||||
|
||||
if (!JetTypeImpl.equalTypes(superValueParameter, subValueParameter, axioms)) {
|
||||
if (!JetTypeChecker.INSTANCE.equalTypes(superValueParameter, subValueParameter, axioms)) {
|
||||
return OverrideCompatibilityInfo.valueParameterTypeMismatch(superValueParameter, subValueParameter);
|
||||
}
|
||||
}
|
||||
@@ -174,7 +174,6 @@ public class OverridingUtil {
|
||||
return OverrideCompatibilityInfo.success();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static boolean isReturnTypeOkForOverride(@NotNull JetTypeChecker typeChecker, @NotNull CallableDescriptor superDescriptor, @NotNull CallableDescriptor subDescriptor) {
|
||||
List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
|
||||
List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
@@ -16,13 +18,22 @@ import static org.jetbrains.jet.lang.types.Variance.OUT_VARIANCE;
|
||||
public class JetTypeChecker {
|
||||
|
||||
public static final JetTypeChecker INSTANCE = new JetTypeChecker();
|
||||
public static final HashBiMap<TypeConstructor, TypeConstructor> EMPTY_AXIOMS = HashBiMap.create();
|
||||
|
||||
private JetTypeChecker() {
|
||||
}
|
||||
|
||||
public boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
// return new TypeCheckingProcedure().run(subtype, supertype);
|
||||
return TYPE_CHECKER.run(subtype, supertype);
|
||||
return TYPE_CHECKER.isSubtypeOf(subtype, supertype);
|
||||
}
|
||||
|
||||
public boolean equalTypes(@NotNull JetType a, @NotNull JetType b) {
|
||||
return equalTypes(a, b, EMPTY_AXIOMS);
|
||||
}
|
||||
|
||||
public boolean equalTypes(@NotNull JetType a, @NotNull JetType b, @NotNull BiMap<TypeConstructor, TypeConstructor> equalityAxioms) {
|
||||
return TYPE_CHECKER.equalTypes(a, b, equalityAxioms);
|
||||
}
|
||||
|
||||
// This method returns the supertype of the first parameter that has the same constructor
|
||||
@@ -86,8 +97,37 @@ public class JetTypeChecker {
|
||||
this.constraintBuilder = constraintBuilder;
|
||||
}
|
||||
|
||||
public boolean run(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
return isSubtypeOf(subtype, supertype);
|
||||
public boolean equalTypes(@NotNull JetType type1, @NotNull JetType type2, @NotNull BiMap<TypeConstructor, TypeConstructor> equalityAxioms) {
|
||||
if (type1.isNullable() != type2.isNullable()) {
|
||||
return false;
|
||||
}
|
||||
TypeConstructor constructor1 = type1.getConstructor();
|
||||
TypeConstructor constructor2 = type2.getConstructor();
|
||||
if (!constructor1.equals(constructor2)) {
|
||||
TypeConstructor img1 = equalityAxioms.get(constructor1);
|
||||
TypeConstructor img2 = equalityAxioms.get(constructor2);
|
||||
if (!(img1 != null && img1.equals(constructor2)) &&
|
||||
!(img2 != null && img2.equals(constructor1))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
List<TypeProjection> type1Arguments = type1.getArguments();
|
||||
List<TypeProjection> type2Arguments = type2.getArguments();
|
||||
if (type1Arguments.size() != type2Arguments.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < type1Arguments.size(); i++) {
|
||||
TypeProjection typeProjection1 = type1Arguments.get(i);
|
||||
TypeProjection typeProjection2 = type2Arguments.get(i);
|
||||
if (typeProjection1.getProjectionKind() != typeProjection2.getProjectionKind()) {
|
||||
return false;
|
||||
}
|
||||
if (!equalTypes(typeProjection1.getType(), typeProjection2.getType(), equalityAxioms)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
@@ -141,181 +181,4 @@ public class JetTypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
// public static abstract class AbstractTypeCheckingProcedure<T> {
|
||||
//
|
||||
// protected enum StatusAction {
|
||||
// PROCEED(false),
|
||||
// DONE_WITH_CURRENT_TYPE(true),
|
||||
// ABORT_ALL(true);
|
||||
//
|
||||
// private final boolean abort;
|
||||
//
|
||||
// private StatusAction(boolean abort) {
|
||||
// this.abort = abort;
|
||||
// }
|
||||
//
|
||||
// public boolean isAbort() {
|
||||
// return abort;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public final T run(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
// proceedOrStop(subtype, supertype);
|
||||
// return result();
|
||||
// }
|
||||
//
|
||||
// protected abstract StatusAction startForPairOfTypes(@NotNull JetType subtype, @NotNull JetType supertype);
|
||||
//
|
||||
// protected abstract StatusAction noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype);
|
||||
//
|
||||
// protected abstract StatusAction equalTypesRequired(@NotNull JetType subArgumentType, @NotNull JetType superArgumentType);
|
||||
//
|
||||
// protected abstract StatusAction varianceConflictFound(@NotNull TypeProjection subArgument, @NotNull TypeProjection superArgument);
|
||||
//
|
||||
// protected abstract StatusAction doneForPairOfTypes(@NotNull JetType subtype, @NotNull JetType supertype);
|
||||
//
|
||||
// protected abstract T result();
|
||||
//
|
||||
// private StatusAction proceedOrStop(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
// StatusAction statusAction = startForPairOfTypes(subtype, supertype);
|
||||
// if (statusAction.isAbort()) {
|
||||
// return statusAction;
|
||||
// }
|
||||
//
|
||||
// JetType closestSupertype = findCorrespondingSupertype(subtype, supertype);
|
||||
// if (closestSupertype == null) {
|
||||
// return noCorrespondingSupertype(subtype, supertype);
|
||||
// }
|
||||
//
|
||||
// proceed(closestSupertype, supertype);
|
||||
// return doneForPairOfTypes(subtype, supertype);
|
||||
// }
|
||||
//
|
||||
// private void proceed(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
// TypeConstructor constructor = subtype.getConstructor();
|
||||
// assert constructor.equals(supertype.getConstructor()) : constructor + " is not " + supertype.getConstructor();
|
||||
//
|
||||
// List<TypeProjection> subArguments = subtype.getArguments();
|
||||
// List<TypeProjection> superArguments = supertype.getArguments();
|
||||
// List<TypeParameterDescriptor> parameters = constructor.getParameters();
|
||||
//
|
||||
// loop:
|
||||
// for (int i = 0; i < parameters.size(); i++) {
|
||||
// TypeParameterDescriptor parameter = parameters.get(i);
|
||||
// TypeProjection subArgument = subArguments.get(i);
|
||||
// TypeProjection superArgument = superArguments.get(i);
|
||||
//
|
||||
// JetType subArgumentType = subArgument.getType();
|
||||
// JetType superArgumentType = superArgument.getType();
|
||||
//
|
||||
// StatusAction action = null;
|
||||
// switch (parameter.getVariance()) {
|
||||
// case INVARIANT:
|
||||
// switch (superArgument.getProjectionKind()) {
|
||||
// case INVARIANT:
|
||||
// action = equalTypesRequired(subArgumentType, superArgumentType);
|
||||
// break;
|
||||
// case OUT_VARIANCE:
|
||||
// if (!subArgument.getProjectionKind().allowsOutPosition()) {
|
||||
// action = varianceConflictFound(subArgument, superArgument);
|
||||
// }
|
||||
// else {
|
||||
// action = proceedOrStop(subArgumentType, superArgumentType);
|
||||
// }
|
||||
// break;
|
||||
// case IN_VARIANCE:
|
||||
// if (!subArgument.getProjectionKind().allowsInPosition()) {
|
||||
// action = varianceConflictFound(subArgument, superArgument);
|
||||
// }
|
||||
// else {
|
||||
// action = proceedOrStop(superArgumentType, subArgumentType);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// break;
|
||||
// case IN_VARIANCE:
|
||||
// switch (superArgument.getProjectionKind()) {
|
||||
// case INVARIANT:
|
||||
// case IN_VARIANCE:
|
||||
// action = proceedOrStop(superArgumentType, subArgumentType);
|
||||
// break;
|
||||
// case OUT_VARIANCE:
|
||||
// action = proceedOrStop(subArgumentType, superArgumentType);
|
||||
// break;
|
||||
// }
|
||||
// break;
|
||||
// case OUT_VARIANCE:
|
||||
// switch (superArgument.getProjectionKind()) {
|
||||
// case INVARIANT:
|
||||
// case OUT_VARIANCE:
|
||||
// case IN_VARIANCE:
|
||||
// action = proceedOrStop(subArgumentType, superArgumentType);
|
||||
// break;
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// switch (action) {
|
||||
// case ABORT_ALL: break loop;
|
||||
// case DONE_WITH_CURRENT_TYPE:
|
||||
// default:
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
// private static class TypeCheckingProcedure extends AbstractTypeCheckingProcedure<Boolean> {
|
||||
//
|
||||
// private boolean result = true;
|
||||
//
|
||||
// private StatusAction fail() {
|
||||
// result = false;
|
||||
// return StatusAction.ABORT_ALL;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public StatusAction startForPairOfTypes(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
// if (ErrorUtils.isErrorType(subtype) || ErrorUtils.isErrorType(supertype)) {
|
||||
// return StatusAction.DONE_WITH_CURRENT_TYPE;
|
||||
// }
|
||||
// if (!supertype.isNullable() && subtype.isNullable()) {
|
||||
// return fail();
|
||||
// }
|
||||
// if (JetStandardClasses.isNothingOrNullableNothing(subtype)) {
|
||||
// return StatusAction.DONE_WITH_CURRENT_TYPE;
|
||||
// }
|
||||
// return StatusAction.PROCEED;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected StatusAction noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
// return fail();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected StatusAction equalTypesRequired(@NotNull JetType subArgumentType, @NotNull JetType superArgumentType) {
|
||||
// if (!subArgumentType.equals(superArgumentType)) {
|
||||
// return fail();
|
||||
// }
|
||||
// return StatusAction.PROCEED;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected StatusAction varianceConflictFound(@NotNull TypeProjection subArgument, @NotNull TypeProjection superArgument) {
|
||||
// return fail();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected StatusAction doneForPairOfTypes(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
// return StatusAction.PROCEED;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected Boolean result() {
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotatedImpl;
|
||||
@@ -17,8 +15,6 @@ import java.util.List;
|
||||
*/
|
||||
public final class JetTypeImpl extends AnnotatedImpl implements JetType {
|
||||
|
||||
public static final HashBiMap<TypeConstructor,TypeConstructor> EMPTY_AXIOMS = HashBiMap.<TypeConstructor, TypeConstructor>create();
|
||||
|
||||
private final TypeConstructor constructor;
|
||||
private final List<TypeProjection> arguments;
|
||||
private final boolean nullable;
|
||||
@@ -96,7 +92,7 @@ public final class JetTypeImpl extends AnnotatedImpl implements JetType {
|
||||
JetTypeImpl type = (JetTypeImpl) o;
|
||||
|
||||
// TODO
|
||||
return nullable == type.nullable && equalTypes(this, type, EMPTY_AXIOMS);
|
||||
return nullable == type.nullable && JetTypeChecker.INSTANCE.equalTypes(this, type);
|
||||
// if (nullable != type.nullable) return false;
|
||||
// if (arguments != null ? !arguments.equals(type.arguments) : type.arguments != null) return false;
|
||||
// if (constructor != null ? !constructor.equals(type.constructor) : type.constructor != null) return false;
|
||||
@@ -113,38 +109,5 @@ public final class JetTypeImpl extends AnnotatedImpl implements JetType {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean equalTypes(@NotNull JetType type1, @NotNull JetType type2, @NotNull BiMap<TypeConstructor, TypeConstructor> equalityAxioms) {
|
||||
if (type1.isNullable() != type2.isNullable()) {
|
||||
return false;
|
||||
}
|
||||
TypeConstructor constructor1 = type1.getConstructor();
|
||||
TypeConstructor constructor2 = type2.getConstructor();
|
||||
if (!constructor1.equals(constructor2)) {
|
||||
TypeConstructor img1 = equalityAxioms.get(constructor1);
|
||||
TypeConstructor img2 = equalityAxioms.get(constructor2);
|
||||
if (!(img1 != null && img1.equals(constructor2)) &&
|
||||
!(img2 != null && img2.equals(constructor1))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
List<TypeProjection> type1Arguments = type1.getArguments();
|
||||
List<TypeProjection> type2Arguments = type2.getArguments();
|
||||
if (type1Arguments.size() != type2Arguments.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < type1Arguments.size(); i++) {
|
||||
TypeProjection typeProjection1 = type1Arguments.get(i);
|
||||
TypeProjection typeProjection2 = type2Arguments.get(i);
|
||||
if (typeProjection1.getProjectionKind() != typeProjection2.getProjectionKind()) {
|
||||
return false;
|
||||
}
|
||||
if (!equalTypes(typeProjection1.getType(), typeProjection2.getType(), equalityAxioms)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -196,7 +196,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
|
||||
}
|
||||
|
||||
private static class KnownType extends TypeValue {
|
||||
private class KnownType extends TypeValue {
|
||||
|
||||
private final JetType type;
|
||||
|
||||
@@ -377,7 +377,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
for (TypeValue upperBound : typeValue.getUpperBounds()) {
|
||||
if (upperBound instanceof KnownType) {
|
||||
KnownType knownBoundType = (KnownType) upperBound;
|
||||
boolean ok = constraintExpander.run(jetType, knownBoundType.getType());
|
||||
boolean ok = constraintExpander.isSubtypeOf(jetType, knownBoundType.getType());
|
||||
if (!ok) {
|
||||
return new Solution().registerError("Mismatch while expanding constraints");
|
||||
}
|
||||
@@ -565,6 +565,6 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
}
|
||||
|
||||
private static void println(String message) {
|
||||
// System.out.println(message);
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user