use of org.eclipse.n4js.ts.types.util.Variance in project n4js by eclipse.
the class BoundSet method combineInvVar.
/**
* Case: first bound is an equality, while the second isn't: `α = S` and `β Φ T` with Φ either {@code <:} or
* {@code :>}.
*/
private TypeConstraint combineInvVar(TypeBound boundS, TypeBound boundT) {
final InferenceVariable alpha = boundS.left;
final InferenceVariable beta = boundT.left;
final TypeRef S = boundS.right;
final TypeRef T = boundT.right;
final Variance Phi = boundT.variance;
if (alpha == beta) {
// (1) `α = S` and `α Φ T` implies `S Φ T`
return new TypeConstraint(S, T, Phi);
}
// both bounds have different inference variables, i.e. α != β
if (alpha == T.getDeclaredType()) {
// (2) `α = S` and `β Φ α` implies `β Φ S`
return new TypeConstraint(typeRef(beta), S, Phi);
}
if (TypeUtils.isInferenceVariable(S)) {
// first bound is of the form `α = γ` (with γ being another inference variable)
final InferenceVariable gamma = (InferenceVariable) S.getDeclaredType();
if (gamma == beta) {
// (3) `α = β` and `β Φ T` implies `α Φ T`
return new TypeConstraint(typeRef(alpha), T, Phi);
}
if (gamma == T.getDeclaredType()) {
// (4) `α = γ` and `β Φ γ` implies `β Φ α`
return new TypeConstraint(typeRef(beta), typeRef(alpha), Phi);
}
}
// so, S is not an inference variable
if (TypeUtils.isProper(S) && TypeUtils.getReferencedTypeVars(T).contains(alpha)) {
// (5) `α = S` (where S is proper) and `β Φ T` implies `β Φ T[α:=U]`
// returns T[α:=U]
final TypeRef T_subst = substituteInferenceVariable(T, alpha, S);
// performance tweak: avoid unnecessary growth of bounds
removeBound(boundT);
return new TypeConstraint(typeRef(beta), T_subst, Phi);
}
return null;
}
use of org.eclipse.n4js.ts.types.util.Variance in project n4js by eclipse.
the class Reducer method reduceConstraintForTypeArgumentPair.
/**
* Will add a constraint ⟨ leftArg :> rightArg ⟩, taking into account wildcards, closed existential types, and
* definition site variance.
*/
private boolean reduceConstraintForTypeArgumentPair(TypeArgument leftArg, TypeVariable leftParam, TypeArgument rightArg) {
boolean wasAdded = false;
if (leftArg instanceof Wildcard) {
final TypeRef ub = ((Wildcard) leftArg).getDeclaredUpperBound();
if (ub != null) {
wasAdded |= reduce(ub, ts.upperBound(G, rightArg).getValue(), CONTRA);
}
final TypeRef lb = ((Wildcard) leftArg).getDeclaredLowerBound();
if (lb != null) {
wasAdded |= reduce(lb, ts.lowerBound(G, rightArg).getValue(), CO);
}
} else if (rightArg instanceof ExistentialTypeRef) {
// TODO IDE-1653 reconsider this entire case
// re-open the existential type, because we assume it was closed only while adding substitutions
// UPDATE: this is wrong if right.typeArgs already contained an ExistentialTypeRef! (but might be
// an non-harmful over approximation)
final Wildcard w = ((ExistentialTypeRef) rightArg).getWildcard();
final TypeRef ub = w.getDeclaredUpperBound();
if (ub != null) {
wasAdded |= reduce(ub, ts.upperBound(G, leftArg).getValue(), CONTRA);
}
final TypeRef lb = w.getDeclaredLowerBound();
if (lb != null) {
wasAdded |= reduce(lb, ts.lowerBound(G, leftArg).getValue(), CO);
}
} else {
if (!(leftArg instanceof TypeRef)) {
throw new UnsupportedOperationException("unsupported subtype of TypeArgument: " + leftArg.getClass().getName());
}
// due to the assumption of the method, we always have: leftArg :> rightArg
// (so for def-site variance we just look at the left side in this case, i.e. leftParam)
final Variance leftDefSiteVarianceRaw = leftParam.getVariance();
final Variance leftDefSiteVariance = leftDefSiteVarianceRaw != null ? leftDefSiteVarianceRaw : INV;
wasAdded |= reduce(leftArg, rightArg, CONTRA.mult(leftDefSiteVariance));
}
return wasAdded;
}
use of org.eclipse.n4js.ts.types.util.Variance in project n4js by eclipse.
the class InternalTypeSystem method applyRuleSubtypeParameterizedTypeRef.
protected Result<Boolean> applyRuleSubtypeParameterizedTypeRef(final RuleEnvironment G, final RuleApplicationTrace _trace_, final ParameterizedTypeRef leftOriginal, final ParameterizedTypeRef rightOriginal) throws RuleFailedException {
final TypeRef left = RuleEnvironmentExtensions.getReplacement(G, leftOriginal);
final TypeRef right = RuleEnvironmentExtensions.getReplacement(G, rightOriginal);
final Type leftDeclType = left.getDeclaredType();
final Type rightDeclType = right.getDeclaredType();
if (((leftDeclType == null) || (rightDeclType == null))) {
/* true */
if (!true) {
sneakyThrowRuleFailedException("true");
}
} else {
if ((leftDeclType.eIsProxy() || rightDeclType.eIsProxy())) {
/* true */
if (!true) {
sneakyThrowRuleFailedException("true");
}
} else {
if (((leftDeclType instanceof VoidType) || (rightDeclType instanceof VoidType))) {
/* leftDeclType instanceof VoidType && rightDeclType instanceof VoidType */
if (!((leftDeclType instanceof VoidType) && (rightDeclType instanceof VoidType))) {
sneakyThrowRuleFailedException("leftDeclType instanceof VoidType && rightDeclType instanceof VoidType");
}
} else {
if ((((leftDeclType instanceof UndefinedType) || ((leftDeclType instanceof NullType) && (!(rightDeclType instanceof UndefinedType)))) || (rightDeclType instanceof AnyType))) {
/* true */
if (!true) {
sneakyThrowRuleFailedException("true");
}
} else {
if ((((leftDeclType == RuleEnvironmentExtensions.intType(G)) && (rightDeclType == RuleEnvironmentExtensions.numberType(G))) || ((leftDeclType == RuleEnvironmentExtensions.numberType(G)) && (rightDeclType == RuleEnvironmentExtensions.intType(G))))) {
/* true */
if (!true) {
sneakyThrowRuleFailedException("true");
}
} else {
if (((leftDeclType instanceof TEnum) && ((rightDeclType == RuleEnvironmentExtensions.n4EnumType(G)) || (rightDeclType == RuleEnvironmentExtensions.objectType(G))))) {
boolean _hasAnnotation = AnnotationDefinition.STRING_BASED.hasAnnotation(leftDeclType);
/* !AnnotationDefinition.STRING_BASED.hasAnnotation( leftDeclType ) */
if (!(!_hasAnnotation)) {
sneakyThrowRuleFailedException("!AnnotationDefinition.STRING_BASED.hasAnnotation( leftDeclType )");
}
} else {
if (((leftDeclType instanceof TEnum) && (((rightDeclType == RuleEnvironmentExtensions.n4StringBasedEnumType(G)) || (rightDeclType == RuleEnvironmentExtensions.stringType(G))) || (rightDeclType == RuleEnvironmentExtensions.stringObjectType(G))))) {
/* AnnotationDefinition.STRING_BASED.hasAnnotation( leftDeclType ) */
if (!AnnotationDefinition.STRING_BASED.hasAnnotation(leftDeclType)) {
sneakyThrowRuleFailedException("AnnotationDefinition.STRING_BASED.hasAnnotation( leftDeclType )");
}
} else {
if (((leftDeclType == RuleEnvironmentExtensions.n4StringBasedEnumType(G)) && ((rightDeclType == RuleEnvironmentExtensions.stringType(G)) || (rightDeclType == RuleEnvironmentExtensions.stringObjectType(G))))) {
/* true */
if (!true) {
sneakyThrowRuleFailedException("true");
}
} else {
if (((leftDeclType instanceof PrimitiveType) && (((PrimitiveType) leftDeclType).getAssignmentCompatible() == rightDeclType))) {
/* true */
if (!true) {
sneakyThrowRuleFailedException("true");
}
} else {
if (((rightDeclType instanceof PrimitiveType) && (leftDeclType == ((PrimitiveType) rightDeclType).getAssignmentCompatible()))) {
/* true */
if (!true) {
sneakyThrowRuleFailedException("true");
}
} else {
if (((((leftDeclType instanceof TInterface) && (!(rightDeclType instanceof TInterface))) && Objects.equal(right.getTypingStrategy(), TypingStrategy.NOMINAL)) && (!(((rightDeclType == RuleEnvironmentExtensions.n4ObjectType(G)) || (rightDeclType == RuleEnvironmentExtensions.objectType(G))) || (rightDeclType == RuleEnvironmentExtensions.anyType(G)))))) {
/* false */
if (!false) {
sneakyThrowRuleFailedException("false");
}
} else {
boolean structuralTyping = false;
boolean _isUseSiteStructuralTyping = right.isUseSiteStructuralTyping();
if (_isUseSiteStructuralTyping) {
final StructuralTypingResult result = this.typeSystemHelper.isStructuralSubtype(G, left, right);
boolean _isValue = result.isValue();
boolean _not = (!_isValue);
if (_not) {
/* fail error result.message data PRIORITY_ERROR */
String _message = result.getMessage();
String error = _message;
Object data = TypeSystemErrorExtensions.PRIORITY_ERROR;
throwForExplicitFail(error, new ErrorInformation(null, null, data));
}
structuralTyping = true;
} else {
boolean _isDefSiteStructuralTyping = right.isDefSiteStructuralTyping();
if (_isDefSiteStructuralTyping) {
Pair<TypeRef, TypeRef> _mappedTo = Pair.<TypeRef, TypeRef>of(left, right);
Pair<String, Pair<TypeRef, TypeRef>> _mappedTo_1 = Pair.<String, Pair<TypeRef, TypeRef>>of(RuleEnvironmentExtensions.GUARD_SUBTYPE_PARAMETERIZED_TYPE_REF__STRUCT, _mappedTo);
Object _get = G.get(_mappedTo_1);
final Boolean guard = ((Boolean) _get);
if (((guard == null) || (!(guard).booleanValue()))) {
final StructuralTypingResult result_1 = this.typeSystemHelper.isStructuralSubtype(G, left, right);
boolean _isValue_1 = result_1.isValue();
boolean _not_1 = (!_isValue_1);
if (_not_1) {
boolean _and = false;
boolean _isN4ObjectOnLeftWithDefSite = result_1.isN4ObjectOnLeftWithDefSite();
if (!_isN4ObjectOnLeftWithDefSite) {
_and = false;
} else {
/* G.wrap, (GUARD_SUBTYPE_PARAMETERIZED_TYPE_REF__STRUCT->(left->right))<-true |- left <: right */
RuleEnvironment _wrap = RuleEnvironmentExtensions.wrap(G);
Pair<TypeRef, TypeRef> _mappedTo_2 = Pair.<TypeRef, TypeRef>of(left, right);
Pair<String, Pair<TypeRef, TypeRef>> _mappedTo_3 = Pair.<String, Pair<TypeRef, TypeRef>>of(RuleEnvironmentExtensions.GUARD_SUBTYPE_PARAMETERIZED_TYPE_REF__STRUCT, _mappedTo_2);
boolean _ruleinvocation = subtypeSucceeded(environmentComposition(_wrap, environmentEntry(_mappedTo_3, true)), _trace_, left, right);
_and = _ruleinvocation;
}
if (_and) {
structuralTyping = true;
} else {
/* fail error result.message data PRIORITY_ERROR */
String _message_1 = result_1.getMessage();
String error_1 = _message_1;
Object data_1 = TypeSystemErrorExtensions.PRIORITY_ERROR;
throwForExplicitFail(error_1, new ErrorInformation(null, null, data_1));
}
}
structuralTyping = result_1.isValue();
}
}
}
if ((!structuralTyping)) {
if ((((left.isUseSiteStructuralTyping() || left.isDefSiteStructuralTyping()) && (!(Objects.equal(rightDeclType, RuleEnvironmentExtensions.objectType(G)) && (leftDeclType instanceof TClassifier)))) && (!(leftDeclType instanceof PrimitiveType)))) {
/* fail error "Structural type " + left.typeRefAsString + " is not a subtype of non-structural type " + right.typeRefAsString data PRIORITY_ERROR */
String _typeRefAsString = left.getTypeRefAsString();
String _plus = ("Structural type " + _typeRefAsString);
String _plus_1 = (_plus + " is not a subtype of non-structural type ");
String _typeRefAsString_1 = right.getTypeRefAsString();
String _plus_2 = (_plus_1 + _typeRefAsString_1);
String error_2 = _plus_2;
Object data_2 = TypeSystemErrorExtensions.PRIORITY_ERROR;
throwForExplicitFail(error_2, new ErrorInformation(null, null, data_2));
}
if (((leftDeclType instanceof TypeVariable) || (rightDeclType instanceof TypeVariable))) {
boolean _equals = Objects.equal(leftDeclType, rightDeclType);
if (_equals) {
/* true */
if (!true) {
sneakyThrowRuleFailedException("true");
}
} else {
if ((leftDeclType instanceof TypeVariable)) {
TypeRef _elvis = null;
TypeRef _declaredUpperBound = ((TypeVariable) leftDeclType).getDeclaredUpperBound();
if (_declaredUpperBound != null) {
_elvis = _declaredUpperBound;
} else {
TypeRef _typeVariableImplicitUpperBound = N4JSLanguageUtils.getTypeVariableImplicitUpperBound(G);
_elvis = _typeVariableImplicitUpperBound;
}
final TypeRef ub = _elvis;
/* G |- ub <: right */
subtypeInternal(G, _trace_, ub, right);
} else {
/* false */
if (!false) {
sneakyThrowRuleFailedException("false");
}
}
}
} else {
boolean _equals_1 = Objects.equal(leftDeclType, rightDeclType);
if (_equals_1) {
if (((left.getTypeArgs().size() > 0) && (left.getTypeArgs().size() <= right.getTypeArgs().size()))) {
final int len = Math.min(Math.min(left.getTypeArgs().size(), right.getTypeArgs().size()), rightDeclType.getTypeVars().size());
for (int i = 0; (i < len); i++) {
final TypeArgument leftArg = left.getTypeArgs().get(i);
final TypeArgument rightArg = right.getTypeArgs().get(i);
final Variance variance = rightDeclType.getVarianceOfTypeVar(i);
TypeRef leftArgUpper = null;
/* G |~ leftArg /\ leftArgUpper */
Result<TypeRef> result_2 = upperBoundInternal(G, _trace_, leftArg);
checkAssignableTo(result_2.getFirst(), TypeRef.class);
leftArgUpper = (TypeRef) result_2.getFirst();
TypeRef leftArgLower = null;
/* G |~ leftArg \/ leftArgLower */
Result<TypeRef> result_3 = lowerBoundInternal(G, _trace_, leftArg);
checkAssignableTo(result_3.getFirst(), TypeRef.class);
leftArgLower = (TypeRef) result_3.getFirst();
TypeRef rightArgUpper = null;
/* G |~ rightArg /\ rightArgUpper */
Result<TypeRef> result_4 = upperBoundInternal(G, _trace_, rightArg);
checkAssignableTo(result_4.getFirst(), TypeRef.class);
rightArgUpper = (TypeRef) result_4.getFirst();
TypeRef rightArgLower = null;
/* G |~ rightArg \/ rightArgLower */
Result<TypeRef> result_5 = lowerBoundInternal(G, _trace_, rightArg);
checkAssignableTo(result_5.getFirst(), TypeRef.class);
rightArgLower = (TypeRef) result_5.getFirst();
RuleEnvironment G2 = null;
if (((rightArg instanceof Wildcard) && ((Wildcard) rightArg).isImplicitUpperBoundInEffect())) {
Pair<String, TypeArgument> _mappedTo_4 = Pair.<String, TypeArgument>of(RuleEnvironmentExtensions.GUARD_SUBTYPE_PARAMETERIZED_TYPE_REF__ARGS, rightArg);
Object _get_1 = G.get(_mappedTo_4);
final boolean isGuarded = (_get_1 != null);
if ((!isGuarded)) {
G2 = RuleEnvironmentExtensions.wrap(G);
Pair<String, TypeArgument> _mappedTo_5 = Pair.<String, TypeArgument>of(RuleEnvironmentExtensions.GUARD_SUBTYPE_PARAMETERIZED_TYPE_REF__ARGS, rightArg);
/* G2.add(GUARD_SUBTYPE_PARAMETERIZED_TYPE_REF__ARGS->(rightArg), Boolean.TRUE) */
if (!G2.add(_mappedTo_5, Boolean.TRUE)) {
sneakyThrowRuleFailedException("G2.add(GUARD_SUBTYPE_PARAMETERIZED_TYPE_REF__ARGS->(rightArg), Boolean.TRUE)");
}
} else {
rightArgUpper = RuleEnvironmentExtensions.topTypeRef(G);
G2 = G;
}
} else {
G2 = G;
}
/* { if(variance!=Variance.CONTRA) { G2 |- leftArgUpper <: rightArgUpper } if(variance!=Variance.CO) { G2 |- rightArgLower <: leftArgLower } } or { if(previousFailure.isOrCausedByPriorityError) { fail error stringRep(left) + " is not a subtype of " + stringRep(right) + " due to incompatible type arguments: " + previousFailure.compileMessage data PRIORITY_ERROR } else { fail } } */
{
RuleFailedException previousFailure = null;
try {
boolean _notEquals = (!Objects.equal(variance, Variance.CONTRA));
if (_notEquals) {
/* G2 |- leftArgUpper <: rightArgUpper */
subtypeInternal(G2, _trace_, leftArgUpper, rightArgUpper);
}
boolean _notEquals_1 = (!Objects.equal(variance, Variance.CO));
if (_notEquals_1) {
/* G2 |- rightArgLower <: leftArgLower */
subtypeInternal(G2, _trace_, rightArgLower, leftArgLower);
}
} catch (Exception e) {
previousFailure = extractRuleFailedException(e);
boolean _isOrCausedByPriorityError = TypeSystemErrorExtensions.isOrCausedByPriorityError(previousFailure);
if (_isOrCausedByPriorityError) {
/* fail error stringRep(left) + " is not a subtype of " + stringRep(right) + " due to incompatible type arguments: " + previousFailure.compileMessage data PRIORITY_ERROR */
String _stringRep = this.stringRep(left);
String _plus_3 = (_stringRep + " is not a subtype of ");
String _stringRep_1 = this.stringRep(right);
String _plus_4 = (_plus_3 + _stringRep_1);
String _plus_5 = (_plus_4 + " due to incompatible type arguments: ");
String _compileMessage = TypeSystemErrorExtensions.compileMessage(previousFailure);
String _plus_6 = (_plus_5 + _compileMessage);
String error_3 = _plus_6;
Object data_3 = TypeSystemErrorExtensions.PRIORITY_ERROR;
throwForExplicitFail(error_3, new ErrorInformation(null, null, data_3));
} else {
/* fail */
throwForExplicitFail();
}
}
}
}
}
} else {
List<ParameterizedTypeRef> _xifexpression = null;
if ((leftDeclType instanceof ContainerType<?>)) {
_xifexpression = AllSuperTypeRefsCollector.collect(((ContainerType<?>) leftDeclType));
} else {
_xifexpression = CollectionLiterals.<ParameterizedTypeRef>newArrayList();
}
final List<ParameterizedTypeRef> allSuperTypeRefs = _xifexpression;
List<ParameterizedTypeRef> _collectAllImplicitSuperTypes = RuleEnvironmentExtensions.collectAllImplicitSuperTypes(G, left);
final Iterable<ParameterizedTypeRef> superTypeRefs = Iterables.<ParameterizedTypeRef>concat(allSuperTypeRefs, _collectAllImplicitSuperTypes);
final Function1<ParameterizedTypeRef, Boolean> _function = (ParameterizedTypeRef it) -> {
Type _declaredType = it.getDeclaredType();
return Boolean.valueOf((_declaredType == rightDeclType));
};
boolean _exists = IterableExtensions.<ParameterizedTypeRef>exists(superTypeRefs, _function);
if (_exists) {
final RuleEnvironment localG_left = RuleEnvironmentExtensions.wrap(G);
this.typeSystemHelper.addSubstitutions(localG_left, left);
final Function1<TypeVariable, TypeRef> _function_1 = (TypeVariable it) -> {
return TypeExtensions.ref(it);
};
final TypeRef syntheticTypeRef = TypeExtensions.ref(rightDeclType, ((TypeArgument[]) Conversions.unwrapArray(ListExtensions.<TypeVariable, TypeRef>map(rightDeclType.getTypeVars(), _function_1), TypeArgument.class)));
/* localG_left |- syntheticTypeRef ~> var TypeRef effectiveSuperTypeRef */
TypeRef effectiveSuperTypeRef = null;
Result<TypeArgument> result_2 = substTypeVariablesInternal(localG_left, _trace_, syntheticTypeRef);
checkAssignableTo(result_2.getFirst(), TypeRef.class);
effectiveSuperTypeRef = (TypeRef) result_2.getFirst();
/* G |- effectiveSuperTypeRef <: right */
subtypeInternal(G, _trace_, effectiveSuperTypeRef, right);
} else {
/* false */
if (!false) {
sneakyThrowRuleFailedException("false");
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return new Result<Boolean>(true);
}
Aggregations