New type checking algorithm is used for subtyping constraint generation
This commit is contained in:
@@ -21,7 +21,7 @@ import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lang.types.inference.ConstraintSystem;
|
||||
import org.jetbrains.jet.lang.types.inference.ConstraintSystemSolution;
|
||||
import org.jetbrains.jet.lang.types.inference.SubtypingOnlyConstraintSystem;
|
||||
import org.jetbrains.jet.lang.types.inference.ConstraintSystemImpl;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.*;
|
||||
@@ -414,7 +414,7 @@ public class CallResolver {
|
||||
if (!candidate.getTypeParameters().isEmpty()) {
|
||||
// Type argument inference
|
||||
|
||||
ConstraintSystem constraintSystem = new SubtypingOnlyConstraintSystem();
|
||||
ConstraintSystem constraintSystem = new ConstraintSystemImpl();
|
||||
for (TypeParameterDescriptor typeParameterDescriptor : candidate.getTypeParameters()) {
|
||||
constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); // TODO
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.types.Variance.INVARIANT;
|
||||
import static org.jetbrains.jet.lang.types.Variance.IN_VARIANCE;
|
||||
import static org.jetbrains.jet.lang.types.Variance.OUT_VARIANCE;
|
||||
|
||||
@@ -21,7 +22,7 @@ public class JetTypeChecker {
|
||||
|
||||
public boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
// return new TypeCheckingProcedure().run(subtype, supertype);
|
||||
return new ExplicitInOutTypeCheckingProcedure().run(subtype, supertype);
|
||||
return TYPE_CHECKER.run(subtype, supertype);
|
||||
}
|
||||
|
||||
// This method returns the supertype of the first parameter that has the same constructor
|
||||
@@ -51,7 +52,39 @@ public class JetTypeChecker {
|
||||
return isOutProjected ? JetStandardClasses.getNothingType() : argument.getType();
|
||||
}
|
||||
|
||||
private static class ExplicitInOutTypeCheckingProcedure {
|
||||
/**
|
||||
* Methods of this class return true to continue type checking and false to fail
|
||||
*/
|
||||
public interface TypingConstraintBuilder {
|
||||
boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b);
|
||||
boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype);
|
||||
boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype);
|
||||
}
|
||||
|
||||
private static final TypeCheckingProcedure TYPE_CHECKER = new TypeCheckingProcedure(new TypingConstraintBuilder() {
|
||||
@Override
|
||||
public boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b) {
|
||||
return TypeUtils.equalTypes(a, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
return INSTANCE.isSubtypeOf(subtype, supertype);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
return false; // type checking fails
|
||||
}
|
||||
});
|
||||
|
||||
public static class TypeCheckingProcedure {
|
||||
|
||||
private final TypingConstraintBuilder constraintBuilder;
|
||||
|
||||
public TypeCheckingProcedure(TypingConstraintBuilder constraintBuilder) {
|
||||
this.constraintBuilder = constraintBuilder;
|
||||
}
|
||||
|
||||
public boolean run(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
return isSubtypeOf(subtype, supertype);
|
||||
@@ -69,7 +102,7 @@ public class JetTypeChecker {
|
||||
}
|
||||
@Nullable JetType closestSupertype = findCorrespondingSupertype(subtype, supertype);
|
||||
if (closestSupertype == null) {
|
||||
return false;
|
||||
if (!constraintBuilder.noCorrespondingSupertype(subtype, supertype)) return false;
|
||||
}
|
||||
|
||||
return checkSubtypeForTheSameConstructor(closestSupertype, supertype);
|
||||
@@ -84,6 +117,7 @@ public class JetTypeChecker {
|
||||
List<TypeParameterDescriptor> parameters = constructor.getParameters();
|
||||
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
|
||||
TypeParameterDescriptor parameter = parameters.get(i);
|
||||
|
||||
|
||||
TypeProjection subArgument = subArguments.get(i);
|
||||
JetType subIn = getInType(parameter, subArgument);
|
||||
@@ -93,189 +127,193 @@ public class JetTypeChecker {
|
||||
JetType superIn = getInType(parameter, superArgument);
|
||||
JetType superOut = getOutType(parameter, superArgument);
|
||||
|
||||
if (!isSubtypeOf(subOut, superOut) || !isSubtypeOf(superIn, subIn)) {
|
||||
return false;
|
||||
if (parameter.getVariance() == INVARIANT && subArgument.getProjectionKind() == INVARIANT && superArgument.getProjectionKind() == INVARIANT) {
|
||||
if (!constraintBuilder.assertEqualTypes(subArgument.getType(), superArgument.getType())) return false;
|
||||
}
|
||||
else {
|
||||
if (!constraintBuilder.assertSubtype(subOut, superOut)) return false;
|
||||
if (!constraintBuilder.assertSubtype(superIn, subIn)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
+35
-67
@@ -14,7 +14,7 @@ import java.util.Set;
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class SubtypingOnlyConstraintSystem implements ConstraintSystem {
|
||||
public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
|
||||
private static class LoopInTypeVariableConstraintsException extends RuntimeException {
|
||||
private LoopInTypeVariableConstraintsException() {
|
||||
@@ -158,6 +158,39 @@ public class SubtypingOnlyConstraintSystem implements ConstraintSystem {
|
||||
private final Map<TypeParameterDescriptor, UnknownType> unknownTypes = Maps.newHashMap();
|
||||
private final JetTypeChecker typeChecker = JetTypeChecker.INSTANCE;
|
||||
|
||||
private final JetTypeChecker.TypeCheckingProcedure constraintExpander = new JetTypeChecker.TypeCheckingProcedure(new JetTypeChecker.TypingConstraintBuilder() {
|
||||
@Override
|
||||
public boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b) {
|
||||
return TypeUtils.equalTypes(a, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
TypeValue subtypeValue = getTypeValueFor(subtype);
|
||||
TypeValue supertypeValue = getTypeValueFor(supertype);
|
||||
|
||||
if (someUnknown(subtypeValue, supertypeValue)) {
|
||||
addSubtypingConstraintOnTypeValues(subtypeValue, supertypeValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
// If some of the types is an unknown, the constraint is already generated, and we should carry on
|
||||
// otherwise there can be no solution, and we should fail
|
||||
return someUnknown(getTypeValueFor(subtype), getTypeValueFor(supertype));
|
||||
}
|
||||
|
||||
private boolean someUnknown(TypeValue subtypeValue, TypeValue supertypeValue) {
|
||||
return subtypeValue instanceof UnknownType || supertypeValue instanceof UnknownType;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
public ConstraintSystemImpl() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TypeValue getTypeValueFor(@NotNull JetType type) {
|
||||
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
@@ -217,7 +250,7 @@ public class SubtypingOnlyConstraintSystem implements ConstraintSystem {
|
||||
for (TypeValue upperBound : typeValue.getUpperBounds()) {
|
||||
if (upperBound instanceof KnownType) {
|
||||
KnownType knownBoundType = (KnownType) upperBound;
|
||||
boolean ok = new SubtypingConstraintExpander().run(jetType, knownBoundType.getType());
|
||||
boolean ok = constraintExpander.run(jetType, knownBoundType.getType());
|
||||
if (!ok) {
|
||||
return new Solution(true);
|
||||
}
|
||||
@@ -344,72 +377,7 @@ public class SubtypingOnlyConstraintSystem implements ConstraintSystem {
|
||||
|
||||
}
|
||||
|
||||
// private class EqualityConstraintExpander extends JetTypeChecker.AbstractTypeCheckingProcedure<Boolean> {
|
||||
//
|
||||
// }
|
||||
|
||||
private class SubtypingConstraintExpander extends JetTypeChecker.AbstractTypeCheckingProcedure<Boolean> {
|
||||
|
||||
private boolean error = false;
|
||||
|
||||
private StatusAction fail() {
|
||||
error = true;
|
||||
return StatusAction.ABORT_ALL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StatusAction startForPairOfTypes(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
return tryToAddConstraint(subtype, supertype);
|
||||
}
|
||||
|
||||
private StatusAction tryToAddConstraint(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
TypeValue subtypeValue = getTypeValueFor(subtype);
|
||||
TypeValue supertypeValue = getTypeValueFor(supertype);
|
||||
|
||||
if (someUnknown(subtypeValue, supertypeValue)) {
|
||||
addSubtypingConstraintOnTypeValues(subtypeValue, supertypeValue);
|
||||
}
|
||||
return StatusAction.PROCEED;
|
||||
}
|
||||
|
||||
private boolean someUnknown(TypeValue subtypeValue, TypeValue supertypeValue) {
|
||||
return subtypeValue instanceof UnknownType || supertypeValue instanceof UnknownType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StatusAction noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
if (someUnknown(getTypeValueFor(subtype), getTypeValueFor(supertype))) {
|
||||
return StatusAction.PROCEED;
|
||||
}
|
||||
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 !error;
|
||||
}
|
||||
}
|
||||
|
||||
private static void println(String message) {
|
||||
// System.out.println(message);
|
||||
}
|
||||
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
package org.jetbrains.jet.lang.types.inference;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class EqualityBasedConstraintSystem implements ConstraintSystem {
|
||||
|
||||
private abstract class Constraint {
|
||||
private final TypeParameterDescriptor typeParameterDescriptor;
|
||||
|
||||
protected Constraint(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
|
||||
this.typeParameterDescriptor = typeParameterDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TypeParameterDescriptor getTypeParameterDescriptor() {
|
||||
return typeParameterDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
private class Unknown {
|
||||
// T -> variance of its position
|
||||
private final Map<TypeParameterDescriptor, Variance> typeParameters = Maps.newHashMap();
|
||||
private final List<Constraint> constraints = Lists.newArrayList();
|
||||
|
||||
}
|
||||
|
||||
private final Map<TypeParameterDescriptor, Unknown> unknowns = Maps.newHashMap();
|
||||
|
||||
@Override
|
||||
public void registerTypeVariable(@NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull Variance positionVariance) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSubtypingConstraint(@NotNull JetType lower, @NotNull JetType upper) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ConstraintSystemSolution solve() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user