use of org.eclipse.n4js.ts.typeRefs.ComposedTypeRef in project n4js by eclipse.
the class TypeCompareLogic method compare.
/**
* WARNING: fqnProvider may be <code>null</code>, but then the lower/greater info will be unreliable!
*/
/* package */
static int compare(IQualifiedNameProvider fqnProvider, TypeArgument arg1, TypeArgument arg2) {
if (arg1 == arg2) {
return 0;
}
if (arg1 == null) {
return -1;
}
if (arg2 == null) {
return 1;
}
if (arg1 instanceof Wildcard || arg2 instanceof Wildcard) {
if (arg1 instanceof Wildcard && arg2 instanceof Wildcard) {
final Wildcard w1 = (Wildcard) arg1;
final Wildcard w2 = (Wildcard) arg2;
int c;
// lower bounds
c = compare(fqnProvider, w1.getDeclaredLowerBound(), w2.getDeclaredLowerBound());
if (c != 0) {
return c;
}
// upper bounds
c = compare(fqnProvider, w1.getDeclaredUpperBound(), w2.getDeclaredUpperBound());
if (c != 0) {
return c;
}
return 0;
}
return compareEClasses(arg1.eClass(), arg2.eClass());
}
// now, we know we have two TypeRefs
final TypeRef ref1 = (TypeRef) arg1;
final TypeRef ref2 = (TypeRef) arg2;
// @formatter:on
if (ref1 instanceof ExistentialTypeRef && ref2 instanceof ExistentialTypeRef) {
return compare(fqnProvider, ((ExistentialTypeRef) ref1).getWildcard(), ((ExistentialTypeRef) ref2).getWildcard());
}
// its subclasses
if (ref1 instanceof FunctionTypeExprOrRef && ref2 instanceof FunctionTypeExprOrRef) {
final FunctionTypeExprOrRef f1 = (FunctionTypeExprOrRef) ref1;
final FunctionTypeExprOrRef f2 = (FunctionTypeExprOrRef) ref2;
return compareFunctionTypeExprOrRefs(fqnProvider, f1, f2);
}
int c;
c = compareEClasses(ref1.eClass(), ref2.eClass());
if (c != 0) {
return c;
}
// note: ref1 and ref2 are of the same type, otherwise c would not be 0
// declared type
c = compare(fqnProvider, ref1.getDeclaredType(), ref2.getDeclaredType());
if (c != 0) {
return c;
}
// if we got a subclass of StructuralTypeRef -> check properties of StructuralTypeRef beforehand
if (ref1 instanceof StructuralTypeRef) {
final StructuralTypeRef sref1 = (StructuralTypeRef) ref1;
final StructuralTypeRef sref2 = (StructuralTypeRef) ref2;
// note: for simplicity, we here require sref1/sref2.structuralMembers to have the same order
// (we aren't doing a semantic compare anyway)
c = compareComparables(sref1.getTypingStrategy(), sref2.getTypingStrategy());
if (c != 0) {
return c;
}
c = compare(fqnProvider, sref1.getStructuralType(), sref2.getStructuralType());
if (c != 0) {
return c;
}
final Iterator<TStructMember> iter1 = sref1.getStructuralMembers().iterator();
final Iterator<TStructMember> iter2 = sref2.getStructuralMembers().iterator();
while (iter1.hasNext() && iter2.hasNext()) {
c = compareMembers(fqnProvider, iter1.next(), iter2.next());
if (c != 0) {
return c;
}
}
if (iter1.hasNext()) {
return 1;
}
if (iter2.hasNext()) {
return -1;
}
}
if (ref1 instanceof ParameterizedTypeRef) {
final ParameterizedTypeRef pref1 = (ParameterizedTypeRef) ref1;
final ParameterizedTypeRef pref2 = (ParameterizedTypeRef) ref2;
c = compareTypeArguments(fqnProvider, pref1.getTypeArgs(), pref2.getTypeArgs());
if (c != 0) {
return c;
}
} else if (ref1 instanceof ComposedTypeRef) {
final ComposedTypeRef cref1 = (ComposedTypeRef) ref1;
final ComposedTypeRef cref2 = (ComposedTypeRef) ref2;
c = compareTypeArguments(fqnProvider, cref1.getTypeRefs(), cref2.getTypeRefs());
if (c != 0) {
return c;
}
} else if (ref1 instanceof TypeTypeRef) {
final TypeTypeRef cref1 = (TypeTypeRef) ref1;
final TypeTypeRef cref2 = (TypeTypeRef) ref2;
c = compareComparables(cref1.isConstructorRef(), cref2.isConstructorRef());
if (c != 0) {
return c;
}
c = compare(fqnProvider, cref1.getTypeArg(), cref2.getTypeArg());
if (c != 0) {
return c;
}
} else if (ref1 instanceof BoundThisTypeRef) {
final BoundThisTypeRef bref1 = (BoundThisTypeRef) ref1;
final BoundThisTypeRef bref2 = (BoundThisTypeRef) ref2;
c = compare(fqnProvider, bref1.getActualThisTypeRef(), bref2.getActualThisTypeRef());
if (c != 0) {
return c;
}
}
// dynamic
c = Boolean.compare(ref1.isDynamic(), ref2.isDynamic());
if (c != 0) {
return c;
}
return 0;
}
use of org.eclipse.n4js.ts.typeRefs.ComposedTypeRef in project n4js by eclipse.
the class TypeUtils method createNonSimplifiedIntersectionType.
/**
* Creates a new intersection type with the given elements. The elements are copied if they have a container. The
* created intersection type may contain duplicates or nested intersection types, that is, it is not simplified!
*
* @see org.eclipse.n4js.typesystem.N4JSTypeSystem#createSimplifiedIntersection(List, Resource)
* @see org.eclipse.n4js.typesystem.TypeSystemHelper#simplify(RuleEnvironment, ComposedTypeRef)
*/
@SuppressWarnings("javadoc")
public static IntersectionTypeExpression createNonSimplifiedIntersectionType(Iterable<? extends TypeRef> elements) {
IntersectionTypeExpression intersectionType = TypeRefsFactory.eINSTANCE.createIntersectionTypeExpression();
EList<TypeRef> intersectionElements = intersectionType.getTypeRefs();
for (TypeRef e : elements) {
intersectionElements.add(TypeUtils.copyIfContained(e));
}
return intersectionType;
}
use of org.eclipse.n4js.ts.typeRefs.ComposedTypeRef in project n4js by eclipse.
the class TypeUtils method createNonSimplifiedUnionType.
/**
* Creates a new union type with the given elements. The elements are copied if they have a container. The created
* union type may contain duplicates or nested union types, that is, it is not simplified! Thus, the returned type
* is expected to be processed further!
*
* @see org.eclipse.n4js.typesystem.N4JSTypeSystem#createSimplifiedUnion(List, Resource)
* @see org.eclipse.n4js.typesystem.TypeSystemHelper#simplify(RuleEnvironment, ComposedTypeRef)
*/
@SuppressWarnings("javadoc")
public static UnionTypeExpression createNonSimplifiedUnionType(Iterable<? extends TypeRef> elements) {
UnionTypeExpression unionType = TypeRefsFactory.eINSTANCE.createUnionTypeExpression();
EList<TypeRef> unionElements = unionType.getTypeRefs();
for (TypeRef e : elements) {
unionElements.add(TypeUtils.copyIfContained(e));
}
return unionType;
}
use of org.eclipse.n4js.ts.typeRefs.ComposedTypeRef in project n4js by eclipse.
the class ComposedMemberScope method createComposedMember.
/**
* Key method of entire scoping for composed types e.g. union/intersection types. This creates a new TMember as a
* combination of all members of the given name in the type's contained types. If those members cannot be combined
* into a single valid member, this method creates a dummy placeholder.
*/
private TMember createComposedMember(String memberName) {
// check all subScopes for a member of the given name and
// merge the properties of the existing members into 'composedMember'
final Resource resource = EcoreUtilN4.getResource(request.context, composedTypeRef);
ComposedMemberInfoBuilder cmiBuilder = new ComposedMemberInfoBuilder();
cmiBuilder.init(writeAccess, resource, ts);
for (int idx = 0; idx < subScopes.length; idx++) {
final IScope subScope = subScopes[idx];
final TypeRef typeRef = composedTypeRef.getTypeRefs().get(idx);
final Resource res = EcoreUtilN4.getResource(request.context, composedTypeRef);
final RuleEnvironment GwithSubstitutions = ts.createRuleEnvironmentForContext(typeRef, res);
final TMember member = findMemberInSubScope(subScope, memberName);
cmiBuilder.addMember(member, GwithSubstitutions);
}
// produce result
ComposedMemberInfo cmi = cmiBuilder.get();
ComposedMemberFactory cmf = getComposedMemberFactory(cmi);
if (!cmf.isEmpty()) {
// at least one of the subScopes had an element of that name
final TMember result;
if (cmf.isValid()) {
// success case: The element for that name can be merged into a valid composed member
result = cmf.create(memberName);
} else {
// some of the subScopes do not have an element for that name OR
// they do not form a valid composed member (e.g. they are of different kind)
// -> produce a specific error message explaining the incompatibility
// (this error placeholder will be wrapped with a UncommonMemberDescription
// in #getSingleLocalElementByName(QualifiedName) above)
result = createErrorPlaceholder(memberName);
}
// add composed member to ComposedTypeRef's cache (without notifications to avoid cache-clear)
final ComposedMemberCache cache = getOrCreateComposedMemberCache();
if (cache != null) {
EcoreUtilN4.doWithDeliver(false, () -> {
cache.getCachedComposedMembers().add(result);
}, cache);
}
// if cache==null: simply do not cache the composed member (i.e. member won't be contained in a resource!)
return result;
} else {
// -> produce the ordinary "Cannot resolve reference ..." error by returning 'null'
return null;
}
}
use of org.eclipse.n4js.ts.typeRefs.ComposedTypeRef in project n4js by eclipse.
the class InternalTypeSystem method applyRuleSubstTypeVariablesInComposedTypeRef.
protected Result<TypeArgument> applyRuleSubstTypeVariablesInComposedTypeRef(final RuleEnvironment G, final RuleApplicationTrace _trace_, final ComposedTypeRef typeRef) throws RuleFailedException {
// output parameter
ComposedTypeRef result = null;
boolean haveReplacement = false;
final ArrayList<TypeRef> substTypeRefs = CollectionLiterals.<TypeRef>newArrayList();
EList<TypeRef> _typeRefs = typeRef.getTypeRefs();
for (final TypeRef currTypeRef : _typeRefs) {
/* G |- currTypeRef ~> var TypeRef substTypeRef */
TypeRef substTypeRef = null;
Result<TypeArgument> result_1 = substTypeVariablesInternal(G, _trace_, currTypeRef);
checkAssignableTo(result_1.getFirst(), TypeRef.class);
substTypeRef = (TypeRef) result_1.getFirst();
boolean _add = substTypeRefs.add(substTypeRef);
/* substTypeRefs.add(substTypeRef) */
if (!_add) {
sneakyThrowRuleFailedException("substTypeRefs.add(substTypeRef)");
}
haveReplacement = (haveReplacement || (substTypeRef != currTypeRef));
}
if (haveReplacement) {
result = TypeUtils.<ComposedTypeRef>copy(typeRef);
result.getTypeRefs().clear();
/* result.typeRefs.addAll(TypeUtils.copyAll(substTypeRefs)) */
if (!result.getTypeRefs().addAll(TypeUtils.<TypeRef>copyAll(substTypeRefs))) {
sneakyThrowRuleFailedException("result.typeRefs.addAll(TypeUtils.copyAll(substTypeRefs))");
}
} else {
result = typeRef;
}
return new Result<TypeArgument>(result);
}
Aggregations