getValue, getValues methods moved to ConstraintsUtil
This commit is contained in:
@@ -264,9 +264,9 @@ public class Renderers {
|
|||||||
.table(newTable().
|
.table(newTable().
|
||||||
descriptor(inferenceErrorData.descriptor));
|
descriptor(inferenceErrorData.descriptor));
|
||||||
|
|
||||||
JetType type = inferenceErrorData.constraintsSystem.getValue(typeParameterDescriptor);
|
JetType type = ConstraintsUtil.getValue(inferenceErrorData.constraintsSystem.getTypeConstraints(typeParameterDescriptor));
|
||||||
JetType upperBound = typeParameterDescriptor.getUpperBoundsAsType();
|
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()
|
result.text(newText()
|
||||||
.normal(" is not satisfied: inferred type ")
|
.normal(" is not satisfied: inferred type ")
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ public class CallResolver {
|
|||||||
for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
|
for (ValueArgument valueArgument : resolvedValueArgument.getArguments()) {
|
||||||
if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue;
|
if (!JetPsiUtil.isFunctionLiteralWithoutDeclaredParameterTypes(valueArgument.getArgumentExpression())) continue;
|
||||||
|
|
||||||
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintsSystem.getSubstitutor(),
|
addConstraintForValueArgument(valueArgument, valueParameterDescriptor, constraintsSystem.getResultingSubstitutor(),
|
||||||
constraintsSystem, context);
|
constraintsSystem, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -366,7 +366,7 @@ public class CallResolver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
D substitute = (D) descriptor.substitute(constraintsSystem.getSubstitutor());
|
D substitute = (D) descriptor.substitute(constraintsSystem.getResultingSubstitutor());
|
||||||
assert substitute != null;
|
assert substitute != null;
|
||||||
replaceValueParametersWithSubstitutedOnes(resolvedCall, substitute);
|
replaceValueParametersWithSubstitutedOnes(resolvedCall, substitute);
|
||||||
resolvedCall.setResultingDescriptor(substitute); //replacement
|
resolvedCall.setResultingDescriptor(substitute); //replacement
|
||||||
|
|||||||
+4
-7
@@ -53,15 +53,12 @@ public interface ConstraintsSystem {
|
|||||||
|
|
||||||
boolean hasTypeConstructorMismatch();
|
boolean hasTypeConstructorMismatch();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
Set<ConstraintPosition> getTypeConstructorMismatchConstraintPositions();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
TypeConstraints getTypeConstraints(@NotNull TypeParameterDescriptor typeParameterDescriptor);
|
TypeConstraints getTypeConstraints(@NotNull TypeParameterDescriptor typeParameterDescriptor);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
TypeSubstitutor getSubstitutor();
|
TypeSubstitutor getResultingSubstitutor();
|
||||||
|
|
||||||
@Nullable
|
|
||||||
JetType getValue(@NotNull TypeParameterDescriptor typeParameterDescriptor);
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
Collection<ConstraintPosition> getTypeConstructorMismatchConstraintPositions();
|
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-35
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.calls.inference;
|
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.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
@@ -52,25 +52,25 @@ public class ConstraintsSystemImpl implements ConstraintsSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final Map<TypeParameterDescriptor, TypeConstraintsImpl> typeParameterConstraints = Maps.newLinkedHashMap();
|
private final Map<TypeParameterDescriptor, TypeConstraintsImpl> typeParameterConstraints = Maps.newLinkedHashMap();
|
||||||
private final TypeSubstitutor typeSubstitutor;
|
private final TypeSubstitutor resultingSubstitutor;
|
||||||
private final Collection<ConstraintPosition> errorConstraintPositions;
|
private final Set<ConstraintPosition> errorConstraintPositions;
|
||||||
private boolean typeConstructorMismatch;
|
private boolean typeConstructorMismatch;
|
||||||
|
|
||||||
public ConstraintsSystemImpl() {
|
public ConstraintsSystemImpl() {
|
||||||
this(false, Lists.<ConstraintPosition>newArrayList());
|
this(false, Sets.<ConstraintPosition>newHashSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstraintsSystemImpl(boolean typeConstructorMismatch, Collection<ConstraintPosition> errorConstraintPositions) {
|
public ConstraintsSystemImpl(boolean typeConstructorMismatch, Set<ConstraintPosition> errorConstraintPositions) {
|
||||||
this.typeConstructorMismatch = typeConstructorMismatch;
|
this.typeConstructorMismatch = typeConstructorMismatch;
|
||||||
this.errorConstraintPositions = errorConstraintPositions;
|
this.errorConstraintPositions = errorConstraintPositions;
|
||||||
this.typeSubstitutor = TypeSubstitutor.create(new TypeSubstitution() {
|
this.resultingSubstitutor = TypeSubstitutor.create(new TypeSubstitution() {
|
||||||
@Override
|
@Override
|
||||||
public TypeProjection get(TypeConstructor key) {
|
public TypeProjection get(TypeConstructor key) {
|
||||||
DeclarationDescriptor declarationDescriptor = key.getDeclarationDescriptor();
|
DeclarationDescriptor declarationDescriptor = key.getDeclarationDescriptor();
|
||||||
if (declarationDescriptor instanceof TypeParameterDescriptor) {
|
if (declarationDescriptor instanceof TypeParameterDescriptor) {
|
||||||
TypeParameterDescriptor descriptor = (TypeParameterDescriptor) declarationDescriptor;
|
TypeParameterDescriptor descriptor = (TypeParameterDescriptor) declarationDescriptor;
|
||||||
|
|
||||||
JetType value = getValue(descriptor);
|
JetType value = ConstraintsUtil.getValue(getTypeConstraints(descriptor));
|
||||||
if (value != null && !TypeUtils.dependsOnTypeParameterConstructors(value, Collections.singleton(
|
if (value != null && !TypeUtils.dependsOnTypeParameterConstructors(value, Collections.singleton(
|
||||||
DONT_CARE.getConstructor()))) {
|
DONT_CARE.getConstructor()))) {
|
||||||
return new TypeProjection(value);
|
return new TypeProjection(value);
|
||||||
@@ -99,7 +99,7 @@ public class ConstraintsSystemImpl implements ConstraintsSystem {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<ConstraintPosition> getTypeConstructorMismatchConstraintPositions() {
|
public Set<ConstraintPosition> getTypeConstructorMismatchConstraintPositions() {
|
||||||
return errorConstraintPositions;
|
return errorConstraintPositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,13 +140,13 @@ public class ConstraintsSystemImpl implements ConstraintsSystem {
|
|||||||
}
|
}
|
||||||
TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) constrainingTypeDescriptor;
|
TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) constrainingTypeDescriptor;
|
||||||
if (constraintKind == ConstraintKind.SUB_TYPE) {
|
if (constraintKind == ConstraintKind.SUB_TYPE) {
|
||||||
typeParameterConstraints.get(typeParameter).addLowerConstraint(subjectType);
|
typeParameterConstraints.get(typeParameter).addLowerBound(subjectType);
|
||||||
}
|
}
|
||||||
else if (constraintKind == ConstraintKind.SUPER_TYPE) {
|
else if (constraintKind == ConstraintKind.SUPER_TYPE) {
|
||||||
typeParameterConstraints.get(typeParameter).addUpperConstraint(subjectType);
|
typeParameterConstraints.get(typeParameter).addUpperBound(subjectType);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
typeParameterConstraints.get(typeParameter).addEqualConstraint(subjectType);
|
typeParameterConstraints.get(typeParameter).addExactBound(subjectType);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -188,25 +188,6 @@ public class ConstraintsSystemImpl implements ConstraintsSystem {
|
|||||||
errorConstraintPositions.add(constraintPosition);
|
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
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Set<TypeParameterDescriptor> getTypeVariables() {
|
public Set<TypeParameterDescriptor> getTypeVariables() {
|
||||||
@@ -233,7 +214,7 @@ public class ConstraintsSystemImpl implements ConstraintsSystem {
|
|||||||
public boolean hasConflictingParameters() {
|
public boolean hasConflictingParameters() {
|
||||||
for (TypeParameterDescriptor typeParameter : typeParameterConstraints.keySet()) {
|
for (TypeParameterDescriptor typeParameter : typeParameterConstraints.keySet()) {
|
||||||
TypeConstraints typeConstraints = getTypeConstraints(typeParameter);
|
TypeConstraints typeConstraints = getTypeConstraints(typeParameter);
|
||||||
if (typeConstraints != null && !typeConstraints.isSuccessful()) return true;
|
if (typeConstraints != null && ConstraintsUtil.getValues(typeConstraints).size() > 1) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -250,15 +231,15 @@ public class ConstraintsSystemImpl implements ConstraintsSystem {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public TypeSubstitutor getSubstitutor() {
|
public TypeSubstitutor getResultingSubstitutor() {
|
||||||
return typeSubstitutor;
|
return resultingSubstitutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean upperBoundsAreSatisfied() {
|
public boolean upperBoundsAreSatisfied() {
|
||||||
for (TypeParameterDescriptor typeParameter : typeParameterConstraints.keySet()) {
|
for (TypeParameterDescriptor typeParameter : typeParameterConstraints.keySet()) {
|
||||||
JetType type = getValue(typeParameter);
|
JetType type = ConstraintsUtil.getValue(getTypeConstraints(typeParameter));
|
||||||
JetType upperBound = typeParameter.getUpperBoundsAsType();
|
JetType upperBound = typeParameter.getUpperBoundsAsType();
|
||||||
JetType substitute = getSubstitutor().substitute(upperBound, Variance.INVARIANT);
|
JetType substitute = getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT);
|
||||||
|
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
if (substitute == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitute)) {
|
if (substitute == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitute)) {
|
||||||
|
|||||||
+61
-10
@@ -18,27 +18,76 @@ package org.jetbrains.jet.lang.resolve.calls.inference;
|
|||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author svtk
|
* @author svtk
|
||||||
*/
|
*/
|
||||||
public class ConstraintsUtil {
|
public class ConstraintsUtil {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Set<JetType> getValues(@Nullable TypeConstraints typeConstraints) {
|
||||||
|
Set<JetType> 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<JetType> values = getValues(typeConstraints);
|
||||||
|
if (values.size() == 1) {
|
||||||
|
return values.iterator().next();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static TypeParameterDescriptor getFirstConflictingParameter(@NotNull ConstraintsSystem constraintsSystem) {
|
public static TypeParameterDescriptor getFirstConflictingParameter(@NotNull ConstraintsSystem constraintsSystem) {
|
||||||
for (TypeParameterDescriptor typeParameter : constraintsSystem.getTypeVariables()) {
|
for (TypeParameterDescriptor typeParameter : constraintsSystem.getTypeVariables()) {
|
||||||
TypeConstraints constraints = constraintsSystem.getTypeConstraints(typeParameter);
|
TypeConstraints constraints = constraintsSystem.getTypeConstraints(typeParameter);
|
||||||
if (!constraints.getConflicts().isEmpty()) {
|
if (getValues(constraints).size() > 1) {
|
||||||
return typeParameter;
|
return typeParameter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +99,7 @@ public class ConstraintsUtil {
|
|||||||
TypeParameterDescriptor firstConflictingParameter = getFirstConflictingParameter(constraintsSystem);
|
TypeParameterDescriptor firstConflictingParameter = getFirstConflictingParameter(constraintsSystem);
|
||||||
if (firstConflictingParameter == null) return Collections.emptyList();
|
if (firstConflictingParameter == null) return Collections.emptyList();
|
||||||
|
|
||||||
Collection<JetType> conflictingTypes = constraintsSystem.getTypeConstraints(firstConflictingParameter).getConflicts();
|
Collection<JetType> conflictingTypes = getValues(constraintsSystem.getTypeConstraints(firstConflictingParameter));
|
||||||
|
|
||||||
ArrayList<Map<TypeConstructor, TypeProjection>> substitutionContexts = Lists.newArrayList();
|
ArrayList<Map<TypeConstructor, TypeProjection>> substitutionContexts = Lists.newArrayList();
|
||||||
for (JetType type : conflictingTypes) {
|
for (JetType type : conflictingTypes) {
|
||||||
@@ -77,7 +126,8 @@ public class ConstraintsUtil {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JetType getSafeValue(@NotNull ConstraintsSystem constraintsSystem, @NotNull TypeParameterDescriptor typeParameter) {
|
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) {
|
if (type != null) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@@ -87,10 +137,11 @@ public class ConstraintsUtil {
|
|||||||
|
|
||||||
public static boolean checkUpperBoundIsSatisfied(@NotNull ConstraintsSystem constraintsSystem,
|
public static boolean checkUpperBoundIsSatisfied(@NotNull ConstraintsSystem constraintsSystem,
|
||||||
@NotNull TypeParameterDescriptor typeParameter) {
|
@NotNull TypeParameterDescriptor typeParameter) {
|
||||||
assert constraintsSystem.getTypeConstraints(typeParameter) != null;
|
TypeConstraints typeConstraints = constraintsSystem.getTypeConstraints(typeParameter);
|
||||||
JetType type = constraintsSystem.getValue(typeParameter);
|
assert typeConstraints != null;
|
||||||
|
JetType type = getValue(typeConstraints);
|
||||||
JetType upperBound = typeParameter.getUpperBoundsAsType();
|
JetType upperBound = typeParameter.getUpperBoundsAsType();
|
||||||
JetType substitute = constraintsSystem.getSubstitutor().substitute(upperBound, Variance.INVARIANT);
|
JetType substitute = constraintsSystem.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT);
|
||||||
|
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
if (substitute == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitute)) {
|
if (substitute == null || !JetTypeChecker.INSTANCE.isSubtypeOf(type, substitute)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user