use of ceylon.language.Sequence in project ceylon by eclipse.
the class TypeDescriptor method unwrapTupleType.
private static TypeDescriptor.Tuple unwrapTupleType(java.lang.Class<?> klass, Variance[] useSiteVariance, TypeDescriptor[] typeArguments, boolean allOptional) {
if (klass != ceylon.language.Tuple.class || (useSiteVariance != null && useSiteVariance != NO_VARIANCE))
return null;
if (typeArguments.length != 3)
return null;
List<TypeDescriptor> elementTypes = new LinkedList<TypeDescriptor>();
boolean variadic = false;
boolean atLeastOne = false;
int firstDefaulted = allOptional ? 0 : -1;
do {
TypeDescriptor first = typeArguments[1];
TypeDescriptor rest = typeArguments[2];
elementTypes.add(first);
if (rest.equals(Empty.$TypeDescriptor$)) {
// that's the last one
break;
} else if (rest instanceof TypeDescriptor.Tuple) {
Tuple restTuple = (Tuple) rest;
return combineTuples(elementTypes, firstDefaulted, restTuple);
} else if (rest instanceof TypeDescriptor.Class) {
Class restClass = (Class) rest;
if (restClass.getKlass() == ceylon.language.Tuple.class) {
// move to the next one
typeArguments = restClass.getTypeArguments();
// and loop
} else if (restClass.getKlass() == Sequence.class) {
// that's the last one
if (restClass.getTypeArguments().length != 1)
return null;
// add the sequence element type
elementTypes.add(restClass.getTypeArguments()[0]);
variadic = atLeastOne = true;
// and we're done
break;
} else if (restClass.getKlass() == Sequential.class) {
// that's the last one
if (restClass.getTypeArguments().length != 1)
return null;
// add the sequential element type
elementTypes.add(restClass.getTypeArguments()[0]);
variadic = true;
// and we're done
break;
} else {
// no idea
return null;
}
} else if (rest instanceof TypeDescriptor.Union) {
// could be an optional
Union restUnion = (Union) rest;
if (restUnion.members.length != 2)
return null;
TypeDescriptor alternative = null;
if (restUnion.members[0] == Empty.$TypeDescriptor$) {
alternative = restUnion.members[1];
} else if (restUnion.members[1] == Empty.$TypeDescriptor$) {
alternative = restUnion.members[0];
}
if (alternative == null)
return null;
// record the first defaulted if it's the first
if (firstDefaulted == -1) {
// so if we have N elements, N is the index of the first defaulted one (the next element)
firstDefaulted = elementTypes.size();
}
// now, it MUST be a tuple IIRC
if (alternative instanceof TypeDescriptor.Tuple) {
Tuple restTuple = (Tuple) alternative;
return combineTuples(elementTypes, firstDefaulted, restTuple);
} else if (alternative instanceof TypeDescriptor.Class) {
if (((TypeDescriptor.Class) alternative).getKlass() == ceylon.language.Tuple.class) {
// we're good, go on and loop
typeArguments = ((TypeDescriptor.Class) alternative).getTypeArguments();
} else {
// no idea
return null;
}
} else {
// no idea
return null;
}
} else {
// no idea
return null;
}
} while (true);
return new Tuple(variadic, atLeastOne, firstDefaulted, elementTypes.toArray(new TypeDescriptor[elementTypes.size()]));
}
Aggregations