From ab0bc60fbd4dfa1feb148c94ab3539c2bbdceaf9 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Wed, 11 Jul 2012 17:50:47 +0400 Subject: [PATCH] getValue, getValues methods moved to ConstraintsUtil --- .../lang/diagnostics/rendering/Renderers.java | 4 +- .../jet/lang/resolve/calls/CallResolver.java | 4 +- .../calls/inference/ConstraintsSystem.java | 11 ++- .../inference/ConstraintsSystemImpl.java | 51 +++++-------- .../calls/inference/ConstraintsUtil.java | 71 ++++++++++++++++--- 5 files changed, 85 insertions(+), 56 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java index 46ac62c9fae..b9fa0538243 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java @@ -264,9 +264,9 @@ public class Renderers { .table(newTable(). descriptor(inferenceErrorData.descriptor)); - JetType type = inferenceErrorData.constraintsSystem.getValue(typeParameterDescriptor); + JetType type = ConstraintsUtil.getValue(inferenceErrorData.constraintsSystem.getTypeConstraints(typeParameterDescriptor)); JetType upperBound = typeParameterDescriptor.getUpperBoundsAsType(); - JetType substitute = inferenceErrorData.constraintsSystem.getSubstitutor().substitute(upperBound, Variance.INVARIANT); + JetType substitute = inferenceErrorData.constraintsSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT); result.text(newText() .normal(" is not satisfied: inferred type ") diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index d345630389e..c452a12ec8b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -349,7 +349,7 @@ public class CallResolver { for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) { if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue; - addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintsSystem.getSubstitutor(), + addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintsSystem.getResultingSubstitutor(), constraintsSystem, context); } } @@ -366,7 +366,7 @@ public class CallResolver { return; } - D substitute = (D) descriptor.substitute(constraintsSystem.getSubstitutor()); + D substitute = (D) descriptor.substitute(constraintsSystem.getResultingSubstitutor()); assert substitute != null; replaceValueParametersWithSubstitutedOnes(resolvedCall, substitute); resolvedCall.setResultingDescriptor(substitute); //replacement diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystem.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystem.java index cf8e1f20779..a074ac50f6d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystem.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystem.java @@ -53,15 +53,12 @@ public interface ConstraintsSystem { boolean hasTypeConstructorMismatch(); + @NotNull + Set getTypeConstructorMismatchConstraintPositions(); + @Nullable TypeConstraints getTypeConstraints(@NotNull TypeParameterDescriptor typeParameterDescriptor); @NotNull - TypeSubstitutor getSubstitutor(); - - @Nullable - JetType getValue(@NotNull TypeParameterDescriptor typeParameterDescriptor); - - @NotNull - Collection getTypeConstructorMismatchConstraintPositions(); + TypeSubstitutor getResultingSubstitutor(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystemImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystemImpl.java index b174c2a3476..b8b03e4625e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystemImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsSystemImpl.java @@ -16,8 +16,8 @@ package org.jetbrains.jet.lang.resolve.calls.inference; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; @@ -52,25 +52,25 @@ public class ConstraintsSystemImpl implements ConstraintsSystem { } private final Map typeParameterConstraints = Maps.newLinkedHashMap(); - private final TypeSubstitutor typeSubstitutor; - private final Collection errorConstraintPositions; + private final TypeSubstitutor resultingSubstitutor; + private final Set errorConstraintPositions; private boolean typeConstructorMismatch; public ConstraintsSystemImpl() { - this(false, Lists.newArrayList()); + this(false, Sets.newHashSet()); } - public ConstraintsSystemImpl(boolean typeConstructorMismatch, Collection errorConstraintPositions) { + public ConstraintsSystemImpl(boolean typeConstructorMismatch, Set errorConstraintPositions) { this.typeConstructorMismatch = typeConstructorMismatch; this.errorConstraintPositions = errorConstraintPositions; - this.typeSubstitutor = TypeSubstitutor.create(new TypeSubstitution() { + this.resultingSubstitutor = TypeSubstitutor.create(new TypeSubstitution() { @Override public TypeProjection get(TypeConstructor key) { DeclarationDescriptor declarationDescriptor = key.getDeclarationDescriptor(); if (declarationDescriptor instanceof TypeParameterDescriptor) { TypeParameterDescriptor descriptor = (TypeParameterDescriptor) declarationDescriptor; - JetType value = getValue(descriptor); + JetType value = ConstraintsUtil.getValue(getTypeConstraints(descriptor)); if (value != null && !TypeUtils.dependsOnTypeParameterConstructors(value, Collections.singleton( DONT_CARE.getConstructor()))) { return new TypeProjection(value); @@ -99,7 +99,7 @@ public class ConstraintsSystemImpl implements ConstraintsSystem { @NotNull @Override - public Collection getTypeConstructorMismatchConstraintPositions() { + public Set getTypeConstructorMismatchConstraintPositions() { return errorConstraintPositions; } @@ -140,13 +140,13 @@ public class ConstraintsSystemImpl implements ConstraintsSystem { } TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) constrainingTypeDescriptor; if (constraintKind == ConstraintKind.SUB_TYPE) { - typeParameterConstraints.get(typeParameter).addLowerConstraint(subjectType); + typeParameterConstraints.get(typeParameter).addLowerBound(subjectType); } else if (constraintKind == ConstraintKind.SUPER_TYPE) { - typeParameterConstraints.get(typeParameter).addUpperConstraint(subjectType); + typeParameterConstraints.get(typeParameter).addUpperBound(subjectType); } else { - typeParameterConstraints.get(typeParameter).addEqualConstraint(subjectType); + typeParameterConstraints.get(typeParameter).addExactBound(subjectType); } return; } @@ -188,25 +188,6 @@ public class ConstraintsSystemImpl implements ConstraintsSystem { errorConstraintPositions.add(constraintPosition); } - @Nullable - public JetType getValue(@NotNull TypeParameterDescriptor typeParameter) { - //todo all checks - TypeConstraintsImpl typeConstraints = typeParameterConstraints.get(typeParameter); - //todo variance dependance - if (typeConstraints == null) { - //todo assert typeConstraints != null; - return null; - } - if (typeConstraints.getLowerConstraint() != null) { - return typeConstraints.getLowerConstraint(); - } - - if (typeConstraints.getUpperConstraint() != null) { - return typeConstraints.getUpperConstraint(); - } - return null; - } - @NotNull @Override public Set getTypeVariables() { @@ -233,7 +214,7 @@ public class ConstraintsSystemImpl implements ConstraintsSystem { public boolean hasConflictingParameters() { for (TypeParameterDescriptor typeParameter : typeParameterConstraints.keySet()) { TypeConstraints typeConstraints = getTypeConstraints(typeParameter); - if (typeConstraints != null && !typeConstraints.isSuccessful()) return true; + if (typeConstraints != null && ConstraintsUtil.getValues(typeConstraints).size() > 1) return true; } return false; } @@ -250,15 +231,15 @@ public class ConstraintsSystemImpl implements ConstraintsSystem { @NotNull @Override - public TypeSubstitutor getSubstitutor() { - return typeSubstitutor; + public TypeSubstitutor getResultingSubstitutor() { + return resultingSubstitutor; } public boolean upperBoundsAreSatisfied() { for (TypeParameterDescriptor typeParameter : typeParameterConstraints.keySet()) { - JetType type = getValue(typeParameter); + JetType type = ConstraintsUtil.getValue(getTypeConstraints(typeParameter)); JetType upperBound = typeParameter.getUpperBoundsAsType(); - JetType substitute = getSubstitutor().substitute(upperBound, Variance.INVARIANT); + JetType substitute = getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT); if (type != null) { if (substitute == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitute)) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsUtil.java index ce511bd4c4a..f2f8b54b4b5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintsUtil.java @@ -18,27 +18,76 @@ package org.jetbrains.jet.lang.resolve.calls.inference; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; +import java.util.*; /** * @author svtk */ public class ConstraintsUtil { + @NotNull + public static Set getValues(@Nullable TypeConstraints typeConstraints) { + Set values = Sets.newLinkedHashSet(); + if (typeConstraints != null && !typeConstraints.isEmpty()) { + values.addAll(typeConstraints.getExactBounds()); + if (!typeConstraints.getLowerBounds().isEmpty()) { + JetType superTypeOfLowerBounds = CommonSupertypes.commonSupertype(typeConstraints.getLowerBounds()); + if (values.isEmpty()) { + values.add(superTypeOfLowerBounds); + } + for (JetType value : values) { + if (!JetTypeChecker.INSTANCE.isSubtypeOf(superTypeOfLowerBounds, value)) { + values.add(superTypeOfLowerBounds); + break; + } + } + } + if (!typeConstraints.getUpperBounds().isEmpty()) { + //todo subTypeOfUpperBounds + JetType subTypeOfUpperBounds = typeConstraints.getUpperBounds().iterator().next(); //todo + if (values.isEmpty()) { + values.add(subTypeOfUpperBounds); + } + for (JetType value : values) { + if (!JetTypeChecker.INSTANCE.isSubtypeOf(value, subTypeOfUpperBounds)) { + values.add(subTypeOfUpperBounds); + break; + } + } + } + } + return values; + } + + @Nullable + public static JetType getValue(@Nullable TypeConstraints typeConstraints) { + //todo all checks + //todo variance dependance + if (typeConstraints == null) { + //todo assert typeConstraints != null; + return null; + } + Set values = getValues(typeConstraints); + if (values.size() == 1) { + return values.iterator().next(); + } + return null; + } + + + @Nullable public static TypeParameterDescriptor getFirstConflictingParameter(@NotNull ConstraintsSystem constraintsSystem) { for (TypeParameterDescriptor typeParameter : constraintsSystem.getTypeVariables()) { TypeConstraints constraints = constraintsSystem.getTypeConstraints(typeParameter); - if (!constraints.getConflicts().isEmpty()) { + if (getValues(constraints).size() > 1) { return typeParameter; } } @@ -50,7 +99,7 @@ public class ConstraintsUtil { TypeParameterDescriptor firstConflictingParameter = getFirstConflictingParameter(constraintsSystem); if (firstConflictingParameter == null) return Collections.emptyList(); - Collection conflictingTypes = constraintsSystem.getTypeConstraints(firstConflictingParameter).getConflicts(); + Collection conflictingTypes = getValues(constraintsSystem.getTypeConstraints(firstConflictingParameter)); ArrayList> substitutionContexts = Lists.newArrayList(); for (JetType type : conflictingTypes) { @@ -77,7 +126,8 @@ public class ConstraintsUtil { @NotNull public static JetType getSafeValue(@NotNull ConstraintsSystem constraintsSystem, @NotNull TypeParameterDescriptor typeParameter) { - JetType type = constraintsSystem.getValue(typeParameter); + TypeConstraints constraints = constraintsSystem.getTypeConstraints(typeParameter); + JetType type = getValue(constraints); if (type != null) { return type; } @@ -87,10 +137,11 @@ public class ConstraintsUtil { public static boolean checkUpperBoundIsSatisfied(@NotNull ConstraintsSystem constraintsSystem, @NotNull TypeParameterDescriptor typeParameter) { - assert constraintsSystem.getTypeConstraints(typeParameter) != null; - JetType type = constraintsSystem.getValue(typeParameter); + TypeConstraints typeConstraints = constraintsSystem.getTypeConstraints(typeParameter); + assert typeConstraints != null; + JetType type = getValue(typeConstraints); JetType upperBound = typeParameter.getUpperBoundsAsType(); - JetType substitute = constraintsSystem.getSubstitutor().substitute(upperBound, Variance.INVARIANT); + JetType substitute = constraintsSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT); if (type != null) { if (substitute == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitute)) {