Search in sources :

Example 1 with Sequence

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()]));
}
Also used : Sequence(ceylon.language.Sequence) LinkedList(java.util.LinkedList) TypeDescriptor(org.eclipse.ceylon.compiler.java.runtime.model.TypeDescriptor)

Aggregations

Sequence (ceylon.language.Sequence)1 LinkedList (java.util.LinkedList)1 TypeDescriptor (org.eclipse.ceylon.compiler.java.runtime.model.TypeDescriptor)1