rename
TypeConstraints -> TypeBounds
This commit is contained in:
@@ -246,7 +246,7 @@ public class Renderers {
|
||||
TabledDescriptorRenderer renderer) {
|
||||
TypeParameterDescriptor firstUnknownParameter = null;
|
||||
for (TypeParameterDescriptor typeParameter : inferenceErrorData.constraintSystem.getTypeVariables()) {
|
||||
if (inferenceErrorData.constraintSystem.getTypeConstraints(typeParameter).isEmpty()) {
|
||||
if (inferenceErrorData.constraintSystem.getTypeBounds(typeParameter).isEmpty()) {
|
||||
firstUnknownParameter = typeParameter;
|
||||
break;
|
||||
}
|
||||
@@ -278,7 +278,7 @@ public class Renderers {
|
||||
}
|
||||
assert typeParameterDescriptor != null : errorMessage;
|
||||
|
||||
JetType inferredValueForTypeParameter = systemWithoutWeakConstraints.getTypeConstraints(typeParameterDescriptor).getValue();
|
||||
JetType inferredValueForTypeParameter = systemWithoutWeakConstraints.getTypeBounds(typeParameterDescriptor).getValue();
|
||||
assert inferredValueForTypeParameter != null : errorMessage;
|
||||
|
||||
result.text(newText().normal("Type parameter bound for ").strong(typeParameterDescriptor.getName()).normal(" in "))
|
||||
|
||||
@@ -112,7 +112,7 @@ public class CallResolverUtil {
|
||||
if (returnType == null) return false;
|
||||
|
||||
for (TypeParameterDescriptor typeVariable : constraintSystem.getTypeVariables()) {
|
||||
JetType inferredValueForTypeVariable = constraintSystem.getTypeConstraints(typeVariable).getValue();
|
||||
JetType inferredValueForTypeVariable = constraintSystem.getTypeBounds(typeVariable).getValue();
|
||||
if (inferredValueForTypeVariable == null) {
|
||||
if (TypeUtils.dependsOnTypeParameters(returnType, Collections.singleton(typeVariable))) {
|
||||
return true;
|
||||
|
||||
+4
-5
@@ -18,7 +18,6 @@ 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;
|
||||
@@ -31,7 +30,7 @@ public class ConstraintsUtil {
|
||||
@Nullable
|
||||
public static TypeParameterDescriptor getFirstConflictingParameter(@NotNull ConstraintSystem constraintSystem) {
|
||||
for (TypeParameterDescriptor typeParameter : constraintSystem.getTypeVariables()) {
|
||||
TypeConstraints constraints = constraintSystem.getTypeConstraints(typeParameter);
|
||||
TypeBounds constraints = constraintSystem.getTypeBounds(typeParameter);
|
||||
if (constraints.getValues().size() > 1) {
|
||||
return typeParameter;
|
||||
}
|
||||
@@ -44,7 +43,7 @@ public class ConstraintsUtil {
|
||||
TypeParameterDescriptor firstConflictingParameter = getFirstConflictingParameter(constraintSystem);
|
||||
if (firstConflictingParameter == null) return Collections.emptyList();
|
||||
|
||||
Collection<JetType> conflictingTypes = constraintSystem.getTypeConstraints(firstConflictingParameter).getValues();
|
||||
Collection<JetType> conflictingTypes = constraintSystem.getTypeBounds(firstConflictingParameter).getValues();
|
||||
|
||||
ArrayList<Map<TypeConstructor, TypeProjection>> substitutionContexts = Lists.newArrayList();
|
||||
for (JetType type : conflictingTypes) {
|
||||
@@ -71,7 +70,7 @@ public class ConstraintsUtil {
|
||||
|
||||
@NotNull
|
||||
public static JetType getSafeValue(@NotNull ConstraintSystem constraintSystem, @NotNull TypeParameterDescriptor typeParameter) {
|
||||
JetType type = constraintSystem.getTypeConstraints(typeParameter).getValue();
|
||||
JetType type = constraintSystem.getTypeBounds(typeParameter).getValue();
|
||||
if (type != null) {
|
||||
return type;
|
||||
}
|
||||
@@ -84,7 +83,7 @@ public class ConstraintsUtil {
|
||||
@NotNull TypeParameterDescriptor typeParameter,
|
||||
boolean substituteOtherTypeParametersInBound
|
||||
) {
|
||||
JetType type = constraintSystem.getTypeConstraints(typeParameter).getValue();
|
||||
JetType type = constraintSystem.getTypeBounds(typeParameter).getValue();
|
||||
if (type == null) return true;
|
||||
for (JetType upperBound : typeParameter.getUpperBounds()) {
|
||||
if (!substituteOtherTypeParametersInBound && TypeUtils.dependsOnTypeParameters(upperBound, constraintSystem.getTypeVariables())) {
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ public interface ConstraintSystem {
|
||||
* Returns null if the type variable was not registered.
|
||||
*/
|
||||
@NotNull
|
||||
TypeConstraints getTypeConstraints(@NotNull TypeParameterDescriptor typeVariable);
|
||||
TypeBounds getTypeBounds(@NotNull TypeParameterDescriptor typeVariable);
|
||||
|
||||
/**
|
||||
* Returns a result of solving the constraint system (mapping from the type variable to the resulting type projection). <p/>
|
||||
|
||||
+55
-56
@@ -41,9 +41,8 @@ import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl.ConstraintKind.EQUAL;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl.ConstraintKind.SUB_TYPE;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.inference.TypeConstraintsImpl.BoundKind;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.inference.TypeConstraintsImpl.BoundKind.*;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.inference.TypeConstraintsImpl.Constraint;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.inference.TypeBoundsImpl.BoundKind.*;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.inference.TypeBoundsImpl.Bound;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.CANT_INFER_TYPE_PARAMETER;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.DONT_CARE;
|
||||
|
||||
@@ -53,7 +52,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
SUB_TYPE, EQUAL
|
||||
}
|
||||
|
||||
private final Map<TypeParameterDescriptor, TypeConstraintsImpl> typeParameterConstraints = Maps.newLinkedHashMap();
|
||||
private final Map<TypeParameterDescriptor, TypeBoundsImpl> typeParameterBounds = Maps.newLinkedHashMap();
|
||||
private final Set<ConstraintPosition> errorConstraintPositions = Sets.newHashSet();
|
||||
private final TypeSubstitutor resultingSubstitutor;
|
||||
private final TypeSubstitutor currentSubstitutor;
|
||||
@@ -82,16 +81,16 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
|
||||
@Override
|
||||
public boolean hasConflictingConstraints() {
|
||||
for (TypeConstraintsImpl typeConstraints : typeParameterConstraints.values()) {
|
||||
if (typeConstraints.getValues().size() > 1) return true;
|
||||
for (TypeBoundsImpl typeBounds : typeParameterBounds.values()) {
|
||||
if (typeBounds.getValues().size() > 1) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnknownParameters() {
|
||||
for (TypeConstraintsImpl typeConstraints : typeParameterConstraints.values()) {
|
||||
if (typeConstraints.isEmpty()) {
|
||||
for (TypeBoundsImpl typeBounds : typeParameterBounds.values()) {
|
||||
if (typeBounds.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -145,8 +144,8 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
if (declarationDescriptor instanceof TypeParameterDescriptor) {
|
||||
TypeParameterDescriptor descriptor = (TypeParameterDescriptor) declarationDescriptor;
|
||||
|
||||
if (typeParameterConstraints.containsKey(descriptor)) {
|
||||
JetType value = getTypeConstraints(descriptor).getValue();
|
||||
if (typeParameterBounds.containsKey(descriptor)) {
|
||||
JetType value = getTypeBounds(descriptor).getValue();
|
||||
if (value != null && !TypeUtils.equalsOrContainsAsArgument(value, TypeUtils.DONT_CARE)) {
|
||||
return new TypeProjection(value);
|
||||
}
|
||||
@@ -163,7 +162,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return typeParameterConstraints.toString();
|
||||
return typeParameterBounds.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -179,18 +178,18 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
for (Map.Entry<TypeParameterDescriptor, Variance> entry : typeVariables.entrySet()) {
|
||||
TypeParameterDescriptor typeVariable = entry.getKey();
|
||||
Variance positionVariance = entry.getValue();
|
||||
typeParameterConstraints.put(typeVariable, new TypeConstraintsImpl(typeVariable, positionVariance));
|
||||
typeParameterBounds.put(typeVariable, new TypeBoundsImpl(typeVariable, positionVariance));
|
||||
}
|
||||
TypeSubstitutor constantSubstitutor = TypeUtils.makeConstantSubstitutor(typeParameterConstraints.keySet(), DONT_CARE);
|
||||
for (Map.Entry<TypeParameterDescriptor, TypeConstraintsImpl> entry : typeParameterConstraints.entrySet()) {
|
||||
TypeSubstitutor constantSubstitutor = TypeUtils.makeConstantSubstitutor(typeParameterBounds.keySet(), DONT_CARE);
|
||||
for (Map.Entry<TypeParameterDescriptor, TypeBoundsImpl> entry : typeParameterBounds.entrySet()) {
|
||||
TypeParameterDescriptor typeVariable = entry.getKey();
|
||||
TypeConstraintsImpl typeConstraints = entry.getValue();
|
||||
TypeBoundsImpl typeBounds = entry.getValue();
|
||||
|
||||
for (JetType declaredUpperBound : typeVariable.getUpperBounds()) {
|
||||
if (KotlinBuiltIns.getInstance().getNullableAnyType().equals(declaredUpperBound)) continue; //todo remove this line (?)
|
||||
JetType substitutedBound = constantSubstitutor.substitute(declaredUpperBound, Variance.INVARIANT);
|
||||
if (substitutedBound != null) {
|
||||
typeConstraints.addConstraint(UPPER_BOUND, substitutedBound, ConstraintPosition.getTypeBoundPosition(typeVariable.getIndex()));
|
||||
typeBounds.addBound(UPPER_BOUND, substitutedBound, ConstraintPosition.getTypeBoundPosition(typeVariable.getIndex()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,10 +199,10 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
@NotNull
|
||||
public ConstraintSystem copy() {
|
||||
return replaceTypeVariables(Functions.<TypeParameterDescriptor>identity(),
|
||||
new Function<TypeConstraintsImpl, TypeConstraintsImpl>() {
|
||||
new Function<TypeBoundsImpl, TypeBoundsImpl>() {
|
||||
@Override
|
||||
public TypeConstraintsImpl apply(TypeConstraintsImpl typeConstraints) {
|
||||
return typeConstraints.copy();
|
||||
public TypeBoundsImpl apply(TypeBoundsImpl typeBounds) {
|
||||
return typeBounds.copy();
|
||||
}
|
||||
},
|
||||
Conditions.<ConstraintPosition>alwaysTrue());
|
||||
@@ -212,17 +211,17 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
@NotNull
|
||||
public ConstraintSystem replaceTypeVariables(@NotNull Function<TypeParameterDescriptor, TypeParameterDescriptor> typeVariablesMap) {
|
||||
return replaceTypeVariables(typeVariablesMap,
|
||||
Functions.<TypeConstraintsImpl>identity(),
|
||||
Functions.<TypeBoundsImpl>identity(),
|
||||
Conditions.<ConstraintPosition>alwaysTrue());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConstraintSystem filterConstrains(@NotNull final Condition<ConstraintPosition> condition) {
|
||||
public ConstraintSystem filterConstraints(@NotNull final Condition<ConstraintPosition> condition) {
|
||||
return replaceTypeVariables(Functions.<TypeParameterDescriptor>identity(),
|
||||
new Function<TypeConstraintsImpl, TypeConstraintsImpl>() {
|
||||
new Function<TypeBoundsImpl, TypeBoundsImpl>() {
|
||||
@Override
|
||||
public TypeConstraintsImpl apply(TypeConstraintsImpl typeConstraints) {
|
||||
return typeConstraints.filter(condition);
|
||||
public TypeBoundsImpl apply(TypeBoundsImpl typeBounds) {
|
||||
return typeBounds.filter(condition);
|
||||
}
|
||||
},
|
||||
condition);
|
||||
@@ -230,7 +229,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
|
||||
@NotNull
|
||||
public ConstraintSystem getSystemWithoutWeakConstraints() {
|
||||
return filterConstrains(new Condition<ConstraintPosition>() {
|
||||
return filterConstraints(new Condition<ConstraintPosition>() {
|
||||
@Override
|
||||
public boolean value(ConstraintPosition constraintPosition) {
|
||||
// 'isStrong' for compound means 'has some strong constraints'
|
||||
@@ -248,18 +247,18 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
@NotNull
|
||||
private ConstraintSystem replaceTypeVariables(
|
||||
@NotNull Function<TypeParameterDescriptor, TypeParameterDescriptor> typeVariablesMap,
|
||||
@NotNull Function<TypeConstraintsImpl, TypeConstraintsImpl> typeConstraintsMap,
|
||||
@NotNull Function<TypeBoundsImpl, TypeBoundsImpl> typeBoundsMap,
|
||||
@NotNull Condition<ConstraintPosition> constraintPositionCondition
|
||||
|
||||
) {
|
||||
ConstraintSystemImpl newConstraintSystem = new ConstraintSystemImpl();
|
||||
for (Map.Entry<TypeParameterDescriptor, TypeConstraintsImpl> entry : typeParameterConstraints.entrySet()) {
|
||||
for (Map.Entry<TypeParameterDescriptor, TypeBoundsImpl> entry : typeParameterBounds.entrySet()) {
|
||||
TypeParameterDescriptor typeParameter = entry.getKey();
|
||||
TypeConstraintsImpl typeConstraints = entry.getValue();
|
||||
TypeBoundsImpl typeBounds = entry.getValue();
|
||||
|
||||
TypeParameterDescriptor newTypeParameter = typeVariablesMap.apply(typeParameter);
|
||||
assert newTypeParameter != null;
|
||||
newConstraintSystem.typeParameterConstraints.put(newTypeParameter, typeConstraintsMap.apply(typeConstraints));
|
||||
newConstraintSystem.typeParameterBounds.put(newTypeParameter, typeBoundsMap.apply(typeBounds));
|
||||
}
|
||||
newConstraintSystem.errorConstraintPositions.addAll(ContainerUtil.filter(errorConstraintPositions, constraintPositionCondition));
|
||||
newConstraintSystem.hasErrorInConstrainingTypes = hasErrorInConstrainingTypes;
|
||||
@@ -400,14 +399,14 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
private void generateTypeParameterConstraint(
|
||||
@NotNull JetType parameterType,
|
||||
@NotNull JetType constrainingType,
|
||||
@NotNull BoundKind boundKind,
|
||||
@NotNull TypeBoundsImpl.BoundKind boundKind,
|
||||
@NotNull ConstraintPosition constraintPosition
|
||||
) {
|
||||
TypeConstraintsImpl typeConstraints = getTypeConstraints(parameterType);
|
||||
assert typeConstraints != null : "constraint should be generated only for type variables";
|
||||
TypeBoundsImpl typeBounds = getTypeBounds(parameterType);
|
||||
assert typeBounds != null : "constraint should be generated only for type variables";
|
||||
|
||||
if (!parameterType.isNullable() || !constrainingType.isNullable()) {
|
||||
typeConstraints.addConstraint(boundKind, constrainingType, constraintPosition);
|
||||
typeBounds.addBound(boundKind, constrainingType, constraintPosition);
|
||||
return;
|
||||
}
|
||||
// For parameter type T:
|
||||
@@ -415,36 +414,36 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
// constraint T? >: Int? should transform to T >: Int
|
||||
JetType notNullConstrainingType = TypeUtils.makeNotNullable(constrainingType);
|
||||
if (boundKind == EXACT_BOUND || boundKind == LOWER_BOUND) {
|
||||
typeConstraints.addConstraint(LOWER_BOUND, notNullConstrainingType, constraintPosition);
|
||||
typeBounds.addBound(LOWER_BOUND, notNullConstrainingType, constraintPosition);
|
||||
}
|
||||
// constraint T? <: Int? should transform to T <: Int?
|
||||
if (boundKind == EXACT_BOUND || boundKind == UPPER_BOUND) {
|
||||
typeConstraints.addConstraint(UPPER_BOUND, constrainingType, constraintPosition);
|
||||
typeBounds.addBound(UPPER_BOUND, constrainingType, constraintPosition);
|
||||
}
|
||||
}
|
||||
|
||||
public void processDeclaredBoundConstraints() {
|
||||
for (Map.Entry<TypeParameterDescriptor, TypeConstraintsImpl> entry : typeParameterConstraints.entrySet()) {
|
||||
for (Map.Entry<TypeParameterDescriptor, TypeBoundsImpl> entry : typeParameterBounds.entrySet()) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = entry.getKey();
|
||||
TypeConstraintsImpl typeConstraints = entry.getValue();
|
||||
TypeBoundsImpl typeBounds = entry.getValue();
|
||||
for (JetType declaredUpperBound : typeParameterDescriptor.getUpperBounds()) {
|
||||
//todo order matters here
|
||||
Collection<Constraint> constraints = Lists.newArrayList(typeConstraints.getConstraints());
|
||||
for (Constraint constraint : constraints) {
|
||||
if (constraint.boundKind == LOWER_BOUND || constraint.boundKind == EXACT_BOUND) {
|
||||
Collection<Bound> bounds = Lists.newArrayList(typeBounds.getBounds());
|
||||
for (Bound bound : bounds) {
|
||||
if (bound.kind == LOWER_BOUND || bound.kind == EXACT_BOUND) {
|
||||
ConstraintPosition position = ConstraintPosition.getCompoundConstraintPosition(
|
||||
ConstraintPosition.getTypeBoundPosition(typeParameterDescriptor.getIndex()), constraint.constraintPosition);
|
||||
addSubtypeConstraint(constraint.type, declaredUpperBound, position);
|
||||
ConstraintPosition.getTypeBoundPosition(typeParameterDescriptor.getIndex()), bound.position);
|
||||
addSubtypeConstraint(bound.type, declaredUpperBound, position);
|
||||
}
|
||||
}
|
||||
ClassifierDescriptor declarationDescriptor = declaredUpperBound.getConstructor().getDeclarationDescriptor();
|
||||
if (declarationDescriptor instanceof TypeParameterDescriptor && typeParameterConstraints.containsKey(declarationDescriptor)) {
|
||||
TypeConstraintsImpl typeConstraintsForUpperBound = typeParameterConstraints.get(declarationDescriptor);
|
||||
for (Constraint constraint : typeConstraintsForUpperBound.getConstraints()) {
|
||||
if (constraint.boundKind == UPPER_BOUND || constraint.boundKind == EXACT_BOUND) {
|
||||
if (declarationDescriptor instanceof TypeParameterDescriptor && typeParameterBounds.containsKey(declarationDescriptor)) {
|
||||
TypeBoundsImpl typeBoundsForUpperBound = typeParameterBounds.get(declarationDescriptor);
|
||||
for (Bound bound : typeBoundsForUpperBound.getBounds()) {
|
||||
if (bound.kind == UPPER_BOUND || bound.kind == EXACT_BOUND) {
|
||||
ConstraintPosition position = ConstraintPosition.getCompoundConstraintPosition(
|
||||
ConstraintPosition.getTypeBoundPosition(typeParameterDescriptor.getIndex()), constraint.constraintPosition);
|
||||
typeConstraints.addConstraint(UPPER_BOUND, constraint.type, position);
|
||||
ConstraintPosition.getTypeBoundPosition(typeParameterDescriptor.getIndex()), bound.position);
|
||||
typeBounds.addBound(UPPER_BOUND, bound.type, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -455,29 +454,29 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<TypeParameterDescriptor> getTypeVariables() {
|
||||
return typeParameterConstraints.keySet();
|
||||
return typeParameterBounds.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public TypeConstraints getTypeConstraints(@NotNull TypeParameterDescriptor typeVariable) {
|
||||
TypeConstraintsImpl typeConstraints = typeParameterConstraints.get(typeVariable);
|
||||
assert typeConstraints != null : "TypeParameterDescriptor is not a type variable for constraint system: " + typeVariable;
|
||||
return typeConstraints;
|
||||
public TypeBounds getTypeBounds(@NotNull TypeParameterDescriptor typeVariable) {
|
||||
TypeBoundsImpl typeBounds = typeParameterBounds.get(typeVariable);
|
||||
assert typeBounds != null : "TypeParameterDescriptor is not a type variable for constraint system: " + typeVariable;
|
||||
return typeBounds;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TypeConstraintsImpl getTypeConstraints(@NotNull JetType type) {
|
||||
private TypeBoundsImpl getTypeBounds(@NotNull JetType type) {
|
||||
ClassifierDescriptor parameterDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
if (parameterDescriptor instanceof TypeParameterDescriptor) {
|
||||
return typeParameterConstraints.get(parameterDescriptor);
|
||||
return typeParameterBounds.get(parameterDescriptor);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isMyTypeVariable(@NotNull JetType type) {
|
||||
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
return descriptor instanceof TypeParameterDescriptor && typeParameterConstraints.get(descriptor) != null;
|
||||
return descriptor instanceof TypeParameterDescriptor && typeParameterBounds.get(descriptor) != null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.types.Variance;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
public interface TypeConstraints {
|
||||
public interface TypeBounds {
|
||||
@NotNull
|
||||
Variance getVarianceOfPosition();
|
||||
|
||||
+56
-56
@@ -31,30 +31,30 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
public class TypeConstraintsImpl implements TypeConstraints {
|
||||
public class TypeBoundsImpl implements TypeBounds {
|
||||
public static enum BoundKind {
|
||||
LOWER_BOUND, UPPER_BOUND, EXACT_BOUND
|
||||
}
|
||||
|
||||
public static class Constraint {
|
||||
public static class Bound {
|
||||
public final JetType type;
|
||||
public final BoundKind boundKind;
|
||||
public final ConstraintPosition constraintPosition;
|
||||
public final BoundKind kind;
|
||||
public final ConstraintPosition position;
|
||||
|
||||
public Constraint(@NotNull JetType type, @NotNull BoundKind boundKind, @NotNull ConstraintPosition constraintPosition) {
|
||||
public Bound(@NotNull JetType type, @NotNull BoundKind kind, @NotNull ConstraintPosition position) {
|
||||
this.type = type;
|
||||
this.boundKind = boundKind;
|
||||
this.constraintPosition = constraintPosition;
|
||||
this.kind = kind;
|
||||
this.position = position;
|
||||
}
|
||||
}
|
||||
|
||||
private final TypeParameterDescriptor typeVariable;
|
||||
private final Variance varianceOfPosition;
|
||||
private final Set<Constraint> constraints = Sets.newLinkedHashSet();
|
||||
private final Set<Bound> bounds = Sets.newLinkedHashSet();
|
||||
|
||||
private Collection<JetType> resultValues;
|
||||
|
||||
public TypeConstraintsImpl(
|
||||
public TypeBoundsImpl(
|
||||
@NotNull TypeParameterDescriptor typeVariable,
|
||||
@NotNull Variance varianceOfPosition
|
||||
) {
|
||||
@@ -68,9 +68,9 @@ public class TypeConstraintsImpl implements TypeConstraints {
|
||||
return varianceOfPosition;
|
||||
}
|
||||
|
||||
public void addConstraint(@NotNull BoundKind boundKind, @NotNull JetType type, @NotNull ConstraintPosition constraintPosition) {
|
||||
public void addBound(@NotNull BoundKind kind, @NotNull JetType type, @NotNull ConstraintPosition position) {
|
||||
resultValues = null;
|
||||
constraints.add(new Constraint(type, boundKind, constraintPosition));
|
||||
bounds.add(new Bound(type, kind, position));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,52 +79,52 @@ public class TypeConstraintsImpl implements TypeConstraints {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<Constraint> getConstraints() {
|
||||
return constraints;
|
||||
public Collection<Bound> getBounds() {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<JetType> filterBounds(
|
||||
@NotNull Collection<Constraint> constraints,
|
||||
@NotNull BoundKind boundKind
|
||||
@NotNull Collection<Bound> bounds,
|
||||
@NotNull BoundKind kind
|
||||
) {
|
||||
return filterBounds(constraints, boundKind, null);
|
||||
return filterBounds(bounds, kind, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<JetType> filterBounds(
|
||||
@NotNull Collection<Constraint> constraints,
|
||||
@NotNull BoundKind boundKind,
|
||||
@NotNull Collection<Bound> bounds,
|
||||
@NotNull BoundKind kind,
|
||||
@Nullable Collection<JetType> errorValues
|
||||
) {
|
||||
Set<JetType> result = Sets.newLinkedHashSet();
|
||||
for (Constraint constraint : constraints) {
|
||||
if (constraint.boundKind == boundKind) {
|
||||
if (!ErrorUtils.containsErrorType(constraint.type)) {
|
||||
result.add(constraint.type);
|
||||
for (Bound bound : bounds) {
|
||||
if (bound.kind == kind) {
|
||||
if (!ErrorUtils.containsErrorType(bound.type)) {
|
||||
result.add(bound.type);
|
||||
}
|
||||
else if (errorValues != null) {
|
||||
errorValues.add(constraint.type);
|
||||
errorValues.add(bound.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*package*/ TypeConstraintsImpl copy() {
|
||||
TypeConstraintsImpl typeConstraints = new TypeConstraintsImpl(typeVariable, varianceOfPosition);
|
||||
typeConstraints.constraints.addAll(constraints);
|
||||
typeConstraints.resultValues = resultValues;
|
||||
return typeConstraints;
|
||||
/*package*/ TypeBoundsImpl copy() {
|
||||
TypeBoundsImpl typeBounds = new TypeBoundsImpl(typeVariable, varianceOfPosition);
|
||||
typeBounds.bounds.addAll(bounds);
|
||||
typeBounds.resultValues = resultValues;
|
||||
return typeBounds;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TypeConstraintsImpl filter(@NotNull final Condition<ConstraintPosition> condition) {
|
||||
TypeConstraintsImpl result = new TypeConstraintsImpl(typeVariable, varianceOfPosition);
|
||||
result.constraints.addAll(ContainerUtil.filter(constraints, new Condition<Constraint>() {
|
||||
public TypeBoundsImpl filter(@NotNull final Condition<ConstraintPosition> condition) {
|
||||
TypeBoundsImpl result = new TypeBoundsImpl(typeVariable, varianceOfPosition);
|
||||
result.bounds.addAll(ContainerUtil.filter(bounds, new Condition<Bound>() {
|
||||
@Override
|
||||
public boolean value(Constraint constraint) {
|
||||
return condition.value(constraint.constraintPosition);
|
||||
public boolean value(Bound bound) {
|
||||
return condition.value(bound.position);
|
||||
}
|
||||
}));
|
||||
return result;
|
||||
@@ -144,51 +144,51 @@ public class TypeConstraintsImpl implements TypeConstraints {
|
||||
@Override
|
||||
public Collection<JetType> getValues() {
|
||||
if (resultValues == null) {
|
||||
resultValues = computeValues(constraints);
|
||||
resultValues = computeValues(bounds);
|
||||
}
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Collection<JetType> computeValues(@NotNull Collection<Constraint> constraints) {
|
||||
private static Collection<JetType> computeValues(@NotNull Collection<Bound> bounds) {
|
||||
Set<JetType> values = Sets.newLinkedHashSet();
|
||||
if (constraints.isEmpty()) {
|
||||
if (bounds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
boolean hasStrongConstraint = ContainerUtil.exists(constraints, new Condition<Constraint>() {
|
||||
boolean hasStrongBound = ContainerUtil.exists(bounds, new Condition<Bound>() {
|
||||
@Override
|
||||
public boolean value(Constraint constraint) {
|
||||
return constraint.constraintPosition.isStrong();
|
||||
public boolean value(Bound bound) {
|
||||
return bound.position.isStrong();
|
||||
}
|
||||
});
|
||||
if (!hasStrongConstraint) {
|
||||
if (!hasStrongBound) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Set<JetType> exactBounds = filterBounds(constraints, BoundKind.EXACT_BOUND, values);
|
||||
Set<JetType> exactBounds = filterBounds(bounds, BoundKind.EXACT_BOUND, values);
|
||||
if (exactBounds.size() == 1) {
|
||||
JetType exactBound = exactBounds.iterator().next();
|
||||
if (trySuggestion(exactBound, constraints)) {
|
||||
if (trySuggestion(exactBound, bounds)) {
|
||||
return Collections.singleton(exactBound);
|
||||
}
|
||||
}
|
||||
values.addAll(exactBounds);
|
||||
|
||||
Pair<Collection<JetType>, Collection<JetType>> pair =
|
||||
TypeUtils.filterNumberTypes(filterBounds(constraints, BoundKind.LOWER_BOUND, values));
|
||||
TypeUtils.filterNumberTypes(filterBounds(bounds, BoundKind.LOWER_BOUND, values));
|
||||
Collection<JetType> generalLowerBounds = pair.getFirst();
|
||||
Collection<JetType> numberLowerBounds = pair.getSecond();
|
||||
|
||||
JetType superTypeOfLowerBounds = CommonSupertypes.commonSupertypeForNonDenotableTypes(generalLowerBounds);
|
||||
if (trySuggestion(superTypeOfLowerBounds, constraints)) {
|
||||
if (trySuggestion(superTypeOfLowerBounds, bounds)) {
|
||||
return Collections.singleton(superTypeOfLowerBounds);
|
||||
}
|
||||
ContainerUtil.addIfNotNull(superTypeOfLowerBounds, values);
|
||||
|
||||
Set<JetType> upperBounds = filterBounds(constraints, BoundKind.UPPER_BOUND, values);
|
||||
Set<JetType> upperBounds = filterBounds(bounds, BoundKind.UPPER_BOUND, values);
|
||||
JetType intersectionOfUpperBounds = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
|
||||
if (!upperBounds.isEmpty() && intersectionOfUpperBounds != null) {
|
||||
if (trySuggestion(intersectionOfUpperBounds, constraints)) {
|
||||
if (trySuggestion(intersectionOfUpperBounds, bounds)) {
|
||||
return Collections.singleton(intersectionOfUpperBounds);
|
||||
}
|
||||
}
|
||||
@@ -196,10 +196,10 @@ public class TypeConstraintsImpl implements TypeConstraints {
|
||||
//fun <T> foo(t: T, consumer: Consumer<T>): T
|
||||
//foo(1, c: Consumer<Any>) - infer Int, not Any here
|
||||
|
||||
values.addAll(filterBounds(constraints, BoundKind.UPPER_BOUND));
|
||||
values.addAll(filterBounds(bounds, BoundKind.UPPER_BOUND));
|
||||
|
||||
JetType superTypeOfNumberLowerBounds = TypeUtils.commonSupertypeForNumberTypes(numberLowerBounds);
|
||||
if (trySuggestion(superTypeOfNumberLowerBounds, constraints)) {
|
||||
if (trySuggestion(superTypeOfNumberLowerBounds, bounds)) {
|
||||
return Collections.singleton(superTypeOfNumberLowerBounds);
|
||||
}
|
||||
ContainerUtil.addIfNotNull(superTypeOfNumberLowerBounds, values);
|
||||
@@ -207,7 +207,7 @@ public class TypeConstraintsImpl implements TypeConstraints {
|
||||
if (superTypeOfLowerBounds != null && superTypeOfNumberLowerBounds != null) {
|
||||
JetType superTypeOfAllLowerBounds = CommonSupertypes.commonSupertypeForNonDenotableTypes(
|
||||
Lists.newArrayList(superTypeOfLowerBounds, superTypeOfNumberLowerBounds));
|
||||
if (trySuggestion(superTypeOfAllLowerBounds, constraints)) {
|
||||
if (trySuggestion(superTypeOfAllLowerBounds, bounds)) {
|
||||
return Collections.singleton(superTypeOfAllLowerBounds);
|
||||
}
|
||||
}
|
||||
@@ -216,28 +216,28 @@ public class TypeConstraintsImpl implements TypeConstraints {
|
||||
|
||||
private static boolean trySuggestion(
|
||||
@Nullable JetType suggestion,
|
||||
@NotNull Collection<Constraint> constraints
|
||||
@NotNull Collection<Bound> bounds
|
||||
) {
|
||||
if (suggestion == null) return false;
|
||||
if (!suggestion.getConstructor().isDenotable()) return false;
|
||||
if (filterBounds(constraints, BoundKind.EXACT_BOUND).size() > 1) return false;
|
||||
if (filterBounds(bounds, BoundKind.EXACT_BOUND).size() > 1) return false;
|
||||
|
||||
for (Constraint constraint : constraints) {
|
||||
switch (constraint.boundKind) {
|
||||
for (Bound bound : bounds) {
|
||||
switch (bound.kind) {
|
||||
case LOWER_BOUND:
|
||||
if (!JetTypeChecker.INSTANCE.isSubtypeOf(constraint.type, suggestion)) {
|
||||
if (!JetTypeChecker.INSTANCE.isSubtypeOf(bound.type, suggestion)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case UPPER_BOUND:
|
||||
if (!JetTypeChecker.INSTANCE.isSubtypeOf(suggestion, constraint.type)) {
|
||||
if (!JetTypeChecker.INSTANCE.isSubtypeOf(suggestion, bound.type)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case EXACT_BOUND:
|
||||
if (!JetTypeChecker.INSTANCE.equalTypes(constraint.type, suggestion)) {
|
||||
if (!JetTypeChecker.INSTANCE.equalTypes(bound.type, suggestion)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
Reference in New Issue
Block a user