aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build
diff options
context:
space:
mode:
authorGravatar Francois-Rene Rideau <tunes@google.com>2015-08-31 15:39:09 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2015-08-31 19:20:53 +0000
commit676905a9e828adc5cf6f43893703f93568f37dfe (patch)
tree14399691dc0f18bc3523ffe6c5e516d08c6cc84d /src/main/java/com/google/devtools/build
parentb4d58a27680d84097a5d1d66ab15fdd2efb8eda6 (diff)
Fixes to Skylark function call
Allow a call to a struct's field when it's a function. Check whether a java method exists before issuing KwArg error. -- MOS_MIGRATED_REVID=101937143
Diffstat (limited to 'src/main/java/com/google/devtools/build')
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java40
1 files changed, 29 insertions, 11 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
index 2e90afd3f9..73e8d10c4f 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
@@ -355,10 +355,19 @@ public final class FuncallExpression extends Expression {
// exactly and copy that behaviour.
// TODO(bazel-team): check if this and SkylarkBuiltInFunctions.createObject can be merged.
private Object invokeJavaMethod(
- Object obj, Class<?> objClass, String methodName, List<Object> args) throws EvalException {
+ Object obj, Class<?> objClass, String methodName, List<Object> args, boolean hasKwArgs)
+ throws EvalException {
MethodDescriptor matchingMethod = null;
List<MethodDescriptor> methods = getMethods(objClass, methodName, args.size(), getLocation());
if (methods != null) {
+ if (hasKwArgs) {
+ throw new EvalException(
+ func.getLocation(),
+ String.format(
+ "Keyword arguments are not allowed when calling a java method"
+ + "\nwhile calling method '%s' on object of type %s",
+ func.getName(), EvalUtils.getDataTypeNameFromClass(objClass)));
+ }
for (MethodDescriptor method : methods) {
Class<?>[] params = method.getMethod().getParameterTypes();
int i = 0;
@@ -508,25 +517,34 @@ public final class FuncallExpression extends Expression {
return convertFromSkylark(
function.call(posargs.build(), ImmutableMap.<String, Object>copyOf(kwargs), this, env),
env);
+ } else if (objValue instanceof ClassObject) {
+ Object fieldValue = ((ClassObject) objValue).getValue(func.getName());
+ if (fieldValue == null) {
+ throw new EvalException(
+ getLocation(), String.format("struct has no method '%s'", func.getName()));
+ }
+ if (!(fieldValue instanceof BaseFunction)) {
+ throw new EvalException(
+ getLocation(), String.format("struct field '%s' is not a function", func.getName()));
+ }
+ function = (BaseFunction) fieldValue;
+ evalArguments(posargs, kwargs, env, function);
+ return convertFromSkylark(
+ function.call(posargs.build(), ImmutableMap.<String, Object>copyOf(kwargs), this, env),
+ env);
} else if (env.isSkylark()) {
// Only allow native Java calls when using Skylark
// When calling a Java method, the name is not in the Environment,
// so evaluating 'func' would fail.
evalArguments(posargs, kwargs, env, null);
- if (!kwargs.isEmpty()) {
- throw new EvalException(
- func.getLocation(),
- String.format(
- "Keyword arguments are not allowed when calling a java method"
- + "\nwhile calling method '%s' on object %s of type %s",
- func.getName(), objValue, EvalUtils.getDataTypeName(objValue)));
- }
if (objValue instanceof Class<?>) {
// Static Java method call. We can return the value from here directly because
// invokeJavaMethod() has special checks.
- return invokeJavaMethod(null, (Class<?>) objValue, func.getName(), posargs.build());
+ return invokeJavaMethod(
+ null, (Class<?>) objValue, func.getName(), posargs.build(), !kwargs.isEmpty());
} else {
- return invokeJavaMethod(objValue, objValue.getClass(), func.getName(), posargs.build());
+ return invokeJavaMethod(
+ objValue, objValue.getClass(), func.getName(), posargs.build(), !kwargs.isEmpty());
}
} else {
throw new EvalException(