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();
}
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);
}
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");
}
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");
}
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());
}
Aggregations