Search in sources :

Example 1 with NoneType

use of com.google.devtools.build.lib.syntax.Runtime.NoneType in project bazel by bazelbuild.

the class FuncallExpression method convertArgumentList.

/**
   * Constructs the parameters list to actually pass to the method, filling with default values if
   * any. If there is a type or argument mismatch, returns a result containing an error message.
   */
private ArgumentListConversionResult convertArgumentList(List<Object> args, Map<String, Object> kwargs, MethodDescriptor method) {
    ImmutableList.Builder<Object> builder = ImmutableList.builder();
    Class<?>[] params = method.getMethod().getParameterTypes();
    SkylarkCallable callable = method.getAnnotation();
    int mandatoryPositionals = callable.mandatoryPositionals();
    if (mandatoryPositionals < 0) {
        if (callable.parameters().length > 0) {
            mandatoryPositionals = 0;
        } else {
            mandatoryPositionals = params.length;
        }
    }
    if (mandatoryPositionals > args.size() || args.size() > mandatoryPositionals + callable.parameters().length) {
        return ArgumentListConversionResult.fromError("too many arguments");
    }
    // First process the legacy positional parameters.
    int i = 0;
    if (mandatoryPositionals > 0) {
        for (Class<?> param : params) {
            Object value = args.get(i);
            if (!param.isAssignableFrom(value.getClass())) {
                return ArgumentListConversionResult.fromError(String.format("Cannot convert parameter at position %d from type %s to type %s", i, EvalUtils.getDataTypeName(value), param.toString()));
            }
            builder.add(value);
            i++;
            if (mandatoryPositionals >= 0 && i >= mandatoryPositionals) {
                // Stops for specified parameters instead.
                break;
            }
        }
    }
    // Then the parameters specified in callable.parameters()
    Set<String> keys = new HashSet<>(kwargs.keySet());
    for (Param param : callable.parameters()) {
        SkylarkType type = getType(param);
        if (param.noneable()) {
            type = SkylarkType.Union.of(type, SkylarkType.NONE);
        }
        Object value = null;
        if (i < args.size()) {
            value = args.get(i);
            if (!param.positional()) {
                return ArgumentListConversionResult.fromError(String.format("Parameter '%s' is not positional", param.name()));
            } else if (!type.contains(value)) {
                return ArgumentListConversionResult.fromError(String.format("Cannot convert parameter '%s' to type %s", param.name(), type.toString()));
            }
            i++;
        } else if (param.named() && keys.remove(param.name())) {
            // Named parameters
            value = kwargs.get(param.name());
            if (!type.contains(value)) {
                return ArgumentListConversionResult.fromError(String.format("Cannot convert parameter '%s' to type %s", param.name(), type.toString()));
            }
        } else {
            // Use default value
            if (param.defaultValue().isEmpty()) {
                return ArgumentListConversionResult.fromError(String.format("parameter '%s' has no default value", param.name()));
            }
            value = SkylarkSignatureProcessor.getDefaultValue(param, null);
        }
        builder.add(value);
        if (!param.noneable() && value instanceof NoneType) {
            return ArgumentListConversionResult.fromError(String.format("parameter '%s' cannot be None", param.name()));
        }
    }
    if (i < args.size() || !keys.isEmpty()) {
        return ArgumentListConversionResult.fromError("too many arguments");
    }
    return ArgumentListConversionResult.fromArgumentList(builder.build());
}
Also used : SkylarkCallable(com.google.devtools.build.lib.skylarkinterface.SkylarkCallable) ImmutableList(com.google.common.collect.ImmutableList) NoneType(com.google.devtools.build.lib.syntax.Runtime.NoneType) Param(com.google.devtools.build.lib.skylarkinterface.Param) HashSet(java.util.HashSet)

Aggregations

ImmutableList (com.google.common.collect.ImmutableList)1 Param (com.google.devtools.build.lib.skylarkinterface.Param)1 SkylarkCallable (com.google.devtools.build.lib.skylarkinterface.SkylarkCallable)1 NoneType (com.google.devtools.build.lib.syntax.Runtime.NoneType)1 HashSet (java.util.HashSet)1