Search in sources :

Example 1 with SkylarkCallable

use of com.google.devtools.build.lib.skylarkinterface.SkylarkCallable in project bazel by bazelbuild.

the class SkylarkInterfaceUtilsTest method testGetSkylarkCallableNotFound.

@Test
public void testGetSkylarkCallableNotFound() throws Exception {
    // Null result when no annotation present...
    Method method = MockClassA.class.getMethod("baz");
    SkylarkCallable ann = SkylarkInterfaceUtils.getSkylarkCallable(method);
    assertThat(ann).isNull();
    // ... including when it's only present in a subclass that was bypassed...
    method = MockClassC.class.getMethod("baz");
    ann = SkylarkInterfaceUtils.getSkylarkCallable(MockClassA.class, method);
    assertThat(ann).isNull();
    // ... or when the method itself is only in the subclass that was bypassed.
    method = MockClassC.class.getMethod("qux");
    ann = SkylarkInterfaceUtils.getSkylarkCallable(MockClassA.class, method);
    assertThat(ann).isNull();
}
Also used : SkylarkCallable(com.google.devtools.build.lib.skylarkinterface.SkylarkCallable) Method(java.lang.reflect.Method) Test(org.junit.Test)

Example 2 with SkylarkCallable

use of com.google.devtools.build.lib.skylarkinterface.SkylarkCallable in project bazel by bazelbuild.

the class SkylarkInterfaceUtilsTest method testGetSkylarkCallableBasic.

@Test
public void testGetSkylarkCallableBasic() throws Exception {
    // Normal case. Ensure two-arg form is consistent with one-arg form.
    Method method = MockClassA.class.getMethod("foo");
    SkylarkCallable ann = SkylarkInterfaceUtils.getSkylarkCallable(method);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockClassA#foo");
    SkylarkCallable ann2 = SkylarkInterfaceUtils.getSkylarkCallable(MockClassA.class, method);
    assertThat(ann2).isEqualTo(ann);
}
Also used : SkylarkCallable(com.google.devtools.build.lib.skylarkinterface.SkylarkCallable) Method(java.lang.reflect.Method) Test(org.junit.Test)

Example 3 with SkylarkCallable

use of com.google.devtools.build.lib.skylarkinterface.SkylarkCallable in project bazel by bazelbuild.

the class SkylarkInterfaceUtilsTest method testGetSkylarkCallableIgnoreNonModules.

@Test
public void testGetSkylarkCallableIgnoreNonModules() throws Exception {
    // Don't return SkylarkCallable annotations in classes and interfaces
    // not marked @SkylarkModule.
    Method method = MockClassD.class.getMethod("foo");
    SkylarkCallable ann = SkylarkInterfaceUtils.getSkylarkCallable(method);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockClassC#foo");
}
Also used : SkylarkCallable(com.google.devtools.build.lib.skylarkinterface.SkylarkCallable) Method(java.lang.reflect.Method) Test(org.junit.Test)

Example 4 with SkylarkCallable

use of com.google.devtools.build.lib.skylarkinterface.SkylarkCallable in project bazel by bazelbuild.

the class SkylarkInterfaceUtilsTest method testGetSkylarkCallableSubclassNoSubannotation.

@Test
public void testGetSkylarkCallableSubclassNoSubannotation() throws Exception {
    // Falls back on superclass's annotation. Superclass takes precedence over interface.
    Method method = MockClassC.class.getMethod("bar");
    SkylarkCallable ann = SkylarkInterfaceUtils.getSkylarkCallable(method);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockClassA#bar");
}
Also used : SkylarkCallable(com.google.devtools.build.lib.skylarkinterface.SkylarkCallable) Method(java.lang.reflect.Method) Test(org.junit.Test)

Example 5 with SkylarkCallable

use of com.google.devtools.build.lib.skylarkinterface.SkylarkCallable 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

SkylarkCallable (com.google.devtools.build.lib.skylarkinterface.SkylarkCallable)27 Method (java.lang.reflect.Method)8 Test (org.junit.Test)7 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)6 ImmutableList (com.google.common.collect.ImmutableList)5 RepositoryFunctionException (com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException)5 IOException (java.io.IOException)5 ImmutableMap (com.google.common.collect.ImmutableMap)2 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)2 Param (com.google.devtools.build.lib.skylarkinterface.Param)2 OutputStream (java.io.OutputStream)2 URL (java.net.URL)2 HashSet (java.util.HashSet)2 Map (java.util.Map)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 SkylarkJavaMethodDoc (com.google.devtools.build.docgen.skylark.SkylarkJavaMethodDoc)1 SkylarkModuleDoc (com.google.devtools.build.docgen.skylark.SkylarkModuleDoc)1 Artifact (com.google.devtools.build.lib.actions.Artifact)1 Root (com.google.devtools.build.lib.actions.Root)1 MiddlemanProvider (com.google.devtools.build.lib.analysis.MiddlemanProvider)1