From 68d256c4801648abaa1540cafce3f3c12aba77d6 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 1 Dec 2011 20:19:13 +0300 Subject: [PATCH] Equality moved to type checker --- .../jet/lang/resolve/OverridingUtil.java | 5 +- .../jet/lang/types/JetTypeChecker.java | 223 ++++-------------- .../jetbrains/jet/lang/types/JetTypeImpl.java | 39 +-- .../types/inference/ConstraintSystemImpl.java | 6 +- 4 files changed, 49 insertions(+), 224 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java index 1b50ad703bc..8b032e707ff 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java @@ -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 superTypeParameters = superDescriptor.getTypeParameters(); List subTypeParameters = subDescriptor.getTypeParameters(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeChecker.java index d06f37c4841..da14e4bfd6f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeChecker.java @@ -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 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 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 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 type1Arguments = type1.getArguments(); + List 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 { -// -// 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 subArguments = subtype.getArguments(); -// List superArguments = supertype.getArguments(); -// List 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 { -// -// 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; -// } -// } - - } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java index 69be07784c9..2cbc04af0d2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java @@ -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 EMPTY_AXIOMS = HashBiMap.create(); - private final TypeConstructor constructor; private final List 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 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 type1Arguments = type1.getArguments(); - List 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; - } - } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java index ed5e49d499c..5ccddb2146c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java @@ -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); } } \ No newline at end of file