use of org.eclipse.n4js.ts.typeRefs.TypeRef in project n4js by eclipse.
the class N4JSMemberRedefinitionValidator method isSubTypeResult.
/**
* @param rightThisContextType
* the type to use as context for the "this binding" of the right-hand-side member or <code>null</code>
* to use the default, i.e. the {@link #getCurrentTypeContext() current type context}.
*/
private Result<Boolean> isSubTypeResult(TMember left, Type rightThisContextType, TMember right) {
// will return type of value for fields, function type for methods, type of return value for getters, type of
// parameter for setters
final Resource res = left.eResource();
final TypeRef mainContext = getCurrentTypeContext();
final TypeRef rightThisContext = rightThisContextType != null ? TypeUtils.createTypeRef(rightThisContextType) : mainContext;
final RuleEnvironment G_left = ts.createRuleEnvironmentForContext(mainContext, mainContext, res);
final RuleEnvironment G_right = ts.createRuleEnvironmentForContext(mainContext, rightThisContext, res);
TypeRef typeLeft = ts.tau(left, G_left);
TypeRef typeRight = ts.tau(right, G_right);
// in case of checking compatibility of constructors, we can ignore the return types
// i.e. turn {function(string):this[C]?} into {function(string)}
// (simplifies subtype check and, more importantly, leads to better error messages)
RuleEnvironment G = getCurrentRuleEnvironment();
if (left.isConstructor() && typeLeft instanceof FunctionTypeExprOrRef) {
typeLeft = changeReturnTypeToVoid(G, (FunctionTypeExprOrRef) typeLeft);
}
if (right.isConstructor() && typeRight instanceof FunctionTypeExprOrRef) {
typeRight = changeReturnTypeToVoid(G, (FunctionTypeExprOrRef) typeRight);
}
return ts.subtype(G, typeLeft, typeRight);
}
use of org.eclipse.n4js.ts.typeRefs.TypeRef 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.typeRefs.TypeRef in project n4js by eclipse.
the class BoundSet method combineContraCo.
/**
* Case: `α :> S` and `β <: T`.
*/
private TypeConstraint combineContraCo(TypeBound boundS, TypeBound boundT) {
final InferenceVariable alpha = boundS.left;
final InferenceVariable beta = boundT.left;
final TypeRef S = boundS.right;
final TypeRef T = boundT.right;
if (alpha == beta) {
// α :> S and α <: T implies S <: T
return new TypeConstraint(S, T, CO);
}
// so, α and β are different
if (TypeUtils.isInferenceVariable(S)) {
final InferenceVariable gamma = (InferenceVariable) S.getDeclaredType();
if (gamma == T.getDeclaredType()) {
// α :> γ and β <: γ implies α :> β
return new TypeConstraint(typeRef(alpha), typeRef(beta), CONTRA);
}
}
return null;
}
use of org.eclipse.n4js.ts.typeRefs.TypeRef in project n4js by eclipse.
the class InferenceContext method resolve.
// ###############################################################################################################
// RESOLUTION
/**
* Performs resolution of all inference variables of the receiving inference context. This might trigger further
* reduction and incorporation steps.
* <p>
* If a solution is found, <code>true</code> is returned and {@link #currentBounds} will contain instantiations for
* all inference variables. Otherwise, <code>false</code> is returned and {@link #currentBounds} will be in an
* undefined state.
*/
private boolean resolve() {
Set<InferenceVariable> currVariableSet;
while ((currVariableSet = getSmallestVariableSet(inferenceVariables)) != null) {
for (InferenceVariable currVariable : currVariableSet) {
if (DEBUG) {
log("======");
log("trying to resolve inference variable: " + str(currVariable));
log("based on this bound set:");
Arrays.stream(currentBounds.getAllBounds()).forEachOrdered(b -> log(" " + b.toString()));
}
final TypeRef instantiation = chooseInstantiation(currVariable);
if (instantiation == null) {
if (DEBUG) {
log("NO INSTANTIATION found for inference variable: " + str(currVariable));
}
return false;
} else {
if (DEBUG) {
log("choosing instantiation " + str(currVariable) + " := " + str(instantiation));
}
instantiate(currVariable, instantiation);
}
}
currentBounds.incorporate();
if (isDoomed()) {
return false;
}
}
return true;
}
use of org.eclipse.n4js.ts.typeRefs.TypeRef in project n4js by eclipse.
the class InferenceContext method containsInterestingLowerBound.
private boolean containsInterestingLowerBound(TypeRef[] typeRefs) {
final Type undefinedType = RuleEnvironmentExtensions.undefinedType(G);
final Type nullType = RuleEnvironmentExtensions.nullType(G);
for (int i = 0; i < typeRefs.length; i++) {
final TypeRef curr = typeRefs[i];
if (curr instanceof ParameterizedTypeRef) {
// for ParameterizedTypeRefs, it depends on the declared type:
final Type currDeclType = curr.getDeclaredType();
if (currDeclType != null && currDeclType != undefinedType && currDeclType != nullType) {
// wow, that bound is interesting!
return true;
}
} else {
// all non-ParameterizedTypeRefs are interesting, except UnknownTypeRef:
if (!(curr instanceof UnknownTypeRef)) {
// wow, that bound looks intriguing!
return true;
}
}
}
// no interesting bounds encountered
return false;
}
Aggregations