Search in sources :

Example 1 with InvocationException

use of ceylon.language.meta.model.InvocationException in project ceylon by eclipse.

the class Metamodel method namedApply.

public static <Return> Return namedApply(Callable<? extends Return> function, DefaultValueProvider defaultValueProvider, org.eclipse.ceylon.model.typechecker.model.Functional declaration, ceylon.language.Iterable<? extends ceylon.language.Entry<? extends ceylon.language.String, ? extends java.lang.Object>, ? extends java.lang.Object> arguments, List<Type> parameterProducedTypes) {
    // FIXME: throw for Java declarations
    java.util.Map<java.lang.String, java.lang.Object> argumentMap = collectArguments(arguments);
    java.util.List<Parameter> parameters = declaration.getFirstParameterList().getParameters();
    // store the values in an array
    Array<java.lang.Object> values = new Array<java.lang.Object>(Anything.$TypeDescriptor$, parameters.size(), (java.lang.Object) null);
    int parameterIndex = 0;
    for (Parameter parameter : parameters) {
        // get the parameter value and remove it so we can keep track of those we used
        java.lang.Object value;
        if (argumentMap.containsKey(parameter.getName())) {
            value = argumentMap.remove(parameter.getName());
            // we have a value: check the type
            Type argumentType = Metamodel.getProducedType(value);
            Type parameterType = parameterProducedTypes.get(parameterIndex);
            if (!argumentType.isSubtypeOf(parameterType))
                throw new ceylon.language.meta.model.IncompatibleTypeException("Invalid argument " + parameter.getName() + ", expected type " + parameterType + " but got " + argumentType);
        } else {
            // make sure it has a default value
            if (!parameter.isDefaulted())
                throw new InvocationException("Missing value for non-defaulted parameter " + parameter.getName());
            // we need to fetch the default value
            value = defaultValueProvider.getDefaultParameterValue(parameter, values, parameterIndex);
            argumentMap.remove(parameter.getName());
        }
        values.set(parameterIndex++, value);
    }
    // do we have extra unknown/unused parameters left?
    if (!argumentMap.isEmpty()) {
        for (String name : argumentMap.keySet()) {
            throw new InvocationException("No such parameter " + name);
        }
    }
    // FIXME: don't we need to spread any variadic param?
    // now do a regular invocation
    Sequential<? extends Object> argumentSequence = values.sequence();
    // we can trust any variadic or pseudo-variadic since we checked parameter by parameter (no spreading possible)
    return Util.apply(function, argumentSequence, null);
}
Also used : IncompatibleTypeException(ceylon.language.meta.model.IncompatibleTypeException) CharArray(org.eclipse.ceylon.compiler.java.language.CharArray) ShortArray(org.eclipse.ceylon.compiler.java.language.ShortArray) BooleanArray(org.eclipse.ceylon.compiler.java.language.BooleanArray) Array(ceylon.language.Array) LongArray(org.eclipse.ceylon.compiler.java.language.LongArray) FloatArray(org.eclipse.ceylon.compiler.java.language.FloatArray) ByteArray(org.eclipse.ceylon.compiler.java.language.ByteArray) ObjectArray(org.eclipse.ceylon.compiler.java.language.ObjectArray) DoubleArray(org.eclipse.ceylon.compiler.java.language.DoubleArray) IntArray(org.eclipse.ceylon.compiler.java.language.IntArray) ReifiedType(org.eclipse.ceylon.compiler.java.runtime.model.ReifiedType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) OpenClassOrInterfaceType(ceylon.language.meta.declaration.OpenClassOrInterfaceType) OpenType(ceylon.language.meta.declaration.OpenType) DeclarationType(org.eclipse.ceylon.model.loader.ModelLoader.DeclarationType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) InvocationException(ceylon.language.meta.model.InvocationException) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Metamodel(org.eclipse.ceylon.compiler.java.runtime.metamodel.Metamodel)

Example 2 with InvocationException

use of ceylon.language.meta.model.InvocationException in project ceylon by eclipse.

the class Metamodel method apply.

public static <Return> Return apply(Callable<? extends Return> function, Sequential<?> arguments, List<Type> parameterProducedTypes, int firstDefaulted, int variadicIndex) {
    int argumentCount = Util.toInt(arguments.getSize());
    int parameters = parameterProducedTypes.size();
    // check minimum
    if (firstDefaulted == -1) {
        if (argumentCount < parameters)
            throw new InvocationException("Not enough arguments to function. Expected " + parameters + " but got only " + argumentCount);
    } else if (argumentCount < firstDefaulted)
        throw new InvocationException("Not enough arguments to function. Expected at least " + firstDefaulted + " but got only " + argumentCount);
    // check maximum
    if (variadicIndex == -1) {
        if (argumentCount > parameters)
            throw new InvocationException("To many arguments to function. Expected at most " + parameters + " but got " + argumentCount);
    }
    // if we're variadic we accept any number
    // now check their types
    Iterator<?> it = arguments.iterator();
    Object arg;
    int i = 0;
    Type variadicElement = null;
    if (variadicIndex != -1)
        // it must be a Sequential<T>
        variadicElement = parameterProducedTypes.get(variadicIndex).getTypeArgumentList().get(0);
    while ((arg = it.next()) != finished_.get_()) {
        Type parameterType = variadicIndex == -1 || i < variadicIndex ? // normal param
        parameterProducedTypes.get(i) : // variadic param
        variadicElement;
        Type argumentType = Metamodel.getProducedType(arg);
        if (!argumentType.isSubtypeOf(parameterType))
            throw new IncompatibleTypeException("Invalid argument " + i + ", expected type " + parameterType + " but got " + argumentType);
        i++;
    }
    // they are all good, let's call it
    TypeDescriptor variadicElementType = variadicElement != null ? Metamodel.getTypeDescriptorForProducedType(variadicElement) : null;
    return Util.apply(function, arguments, variadicElementType);
}
Also used : ReifiedType(org.eclipse.ceylon.compiler.java.runtime.model.ReifiedType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) OpenClassOrInterfaceType(ceylon.language.meta.declaration.OpenClassOrInterfaceType) OpenType(ceylon.language.meta.declaration.OpenType) DeclarationType(org.eclipse.ceylon.model.loader.ModelLoader.DeclarationType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) TypeDescriptor(org.eclipse.ceylon.compiler.java.runtime.model.TypeDescriptor) InvocationException(ceylon.language.meta.model.InvocationException) IncompatibleTypeException(ceylon.language.meta.model.IncompatibleTypeException)

Aggregations

OpenClassOrInterfaceType (ceylon.language.meta.declaration.OpenClassOrInterfaceType)2 OpenType (ceylon.language.meta.declaration.OpenType)2 IncompatibleTypeException (ceylon.language.meta.model.IncompatibleTypeException)2 InvocationException (ceylon.language.meta.model.InvocationException)2 ReifiedType (org.eclipse.ceylon.compiler.java.runtime.model.ReifiedType)2 DeclarationType (org.eclipse.ceylon.model.loader.ModelLoader.DeclarationType)2 NothingType (org.eclipse.ceylon.model.typechecker.model.NothingType)2 Type (org.eclipse.ceylon.model.typechecker.model.Type)2 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)2 Array (ceylon.language.Array)1 BooleanArray (org.eclipse.ceylon.compiler.java.language.BooleanArray)1 ByteArray (org.eclipse.ceylon.compiler.java.language.ByteArray)1 CharArray (org.eclipse.ceylon.compiler.java.language.CharArray)1 DoubleArray (org.eclipse.ceylon.compiler.java.language.DoubleArray)1 FloatArray (org.eclipse.ceylon.compiler.java.language.FloatArray)1 IntArray (org.eclipse.ceylon.compiler.java.language.IntArray)1 LongArray (org.eclipse.ceylon.compiler.java.language.LongArray)1 ObjectArray (org.eclipse.ceylon.compiler.java.language.ObjectArray)1 ShortArray (org.eclipse.ceylon.compiler.java.language.ShortArray)1 Metamodel (org.eclipse.ceylon.compiler.java.runtime.metamodel.Metamodel)1