aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main
diff options
context:
space:
mode:
authorGravatar fzaiser <fzaiser@google.com>2017-08-14 12:00:51 +0200
committerGravatar Irina Iancu <elenairina@google.com>2017-08-14 14:16:22 +0200
commite0f1333de8e1ecd43bdb39992f97b916f00d49ee (patch)
treed768b73aee78b4c0f3aed0424c8a31a325aeae51 /src/main
parent05418b33dd87d63e2653e594d462b2aedb0e22e5 (diff)
Fix Skylark parsing of call expressions.
This allows more complex expressions to be called, not just identifiers. For example, "x[0]()" is not a syntax error anymore. RELNOTES: None PiperOrigin-RevId: 165157981
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java17
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/Parser.java41
2 files changed, 13 insertions, 45 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 6bfa55ad1d..0eb87da305 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
@@ -727,14 +727,13 @@ public final class FuncallExpression extends Expression {
@Override
Object doEval(Environment env) throws EvalException, InterruptedException {
+ // TODO: Remove this special case once method resolution and invocation are supported as
+ // separate steps.
if (function instanceof DotExpression) {
return invokeObjectMethod(env, (DotExpression) function);
}
- if (function instanceof Identifier) {
- return invokeGlobalFunction(env);
- }
- throw new EvalException(
- getLocation(), Printer.format("cannot evaluate function '%s'", function));
+ Object funcValue = function.eval(env);
+ return callFunction(funcValue, env);
}
/** Invokes object.function() and returns the result. */
@@ -752,14 +751,6 @@ public final class FuncallExpression extends Expression {
}
/**
- * Invokes function() and returns the result.
- */
- private Object invokeGlobalFunction(Environment env) throws EvalException, InterruptedException {
- Object funcValue = function.eval(env);
- return callFunction(funcValue, env);
- }
-
- /**
* Calls a function object
*/
private Object callFunction(Object funcValue, Environment env)
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
index 8f5e301fde..03c50d3a3b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
@@ -440,17 +440,6 @@ public class Parser {
return setLocation(node, startOffset, lastNode.getLocation().getEndOffset());
}
- // create a funcall expression
- private Expression makeFuncallExpression(Expression receiver, Identifier function,
- List<Argument.Passed> args,
- int start, int end) {
- if (function.getLocation() == null) {
- function = setLocation(function, start, end);
- }
- Expression fun = receiver == null ? function : new DotExpression(receiver, function);
- return setLocation(new FuncallExpression(fun, args), start, end);
- }
-
// arg ::= IDENTIFIER '=' nontupleexpr
// | expr
// | *args (only in Skylark mode)
@@ -534,7 +523,7 @@ public class Parser {
}
// funcall_suffix ::= '(' arg_list? ')'
- private Expression parseFuncallSuffix(int start, Expression receiver, Identifier function) {
+ private Expression parseFuncallSuffix(int start, Expression function) {
List<Argument.Passed> args = Collections.emptyList();
expect(TokenKind.LPAREN);
int end;
@@ -546,20 +535,15 @@ public class Parser {
end = token.right;
expect(TokenKind.RPAREN);
}
- return makeFuncallExpression(receiver, function, args, start, end);
+ return setLocation(new FuncallExpression(function, args), start, end);
}
// selector_suffix ::= '.' IDENTIFIER
- // |'.' IDENTIFIER funcall_suffix
private Expression parseSelectorSuffix(int start, Expression receiver) {
expect(TokenKind.DOT);
if (token.kind == TokenKind.IDENTIFIER) {
Identifier ident = parseIdent();
- if (token.kind == TokenKind.LPAREN) {
- return parseFuncallSuffix(start, receiver, ident);
- } else {
- return setLocation(new DotExpression(receiver, ident), start, token.right);
- }
+ return setLocation(new DotExpression(receiver, ident), start, token.right);
} else {
syntaxError(token, "expected identifier after dot");
int end = syncTo(EXPR_TERMINATOR_SET);
@@ -643,10 +627,7 @@ public class Parser {
// primary ::= INTEGER
// | STRING
- // | STRING '.' IDENTIFIER funcall_suffix
// | IDENTIFIER
- // | IDENTIFIER funcall_suffix
- // | IDENTIFIER '.' selector_suffix
// | list_expression
// | '(' ')' // a tuple with zero elements
// | '(' expr ')' // a parenthesized expression
@@ -665,14 +646,7 @@ public class Parser {
case STRING:
return parseStringLiteral();
case IDENTIFIER:
- {
- Identifier ident = parseIdent();
- if (token.kind == TokenKind.LPAREN) { // it's a function application
- return parseFuncallSuffix(start, null, ident);
- } else {
- return ident;
- }
- }
+ return parseIdent();
case LBRACKET: // it's a list
return parseListMaker();
case LBRACE: // it's a dictionary
@@ -714,8 +688,7 @@ public class Parser {
}
}
- // primary_with_suffix ::= primary selector_suffix*
- // | primary substring_suffix
+ // primary_with_suffix ::= primary (selector_suffix | substring_suffix | funcall_suffix)*
private Expression parsePrimaryWithSuffix() {
int start = token.left;
Expression receiver = parsePrimary();
@@ -724,6 +697,8 @@ public class Parser {
receiver = parseSelectorSuffix(start, receiver);
} else if (token.kind == TokenKind.LBRACKET) {
receiver = parseSubstringSuffix(start, receiver);
+ } else if (token.kind == TokenKind.LPAREN) {
+ receiver = parseFuncallSuffix(start, receiver);
} else {
break;
}
@@ -732,6 +707,8 @@ public class Parser {
}
// substring_suffix ::= '[' expression? ':' expression? ':' expression? ']'
+ // | '[' expression? ':' expression? ']'
+ // | '[' expression ']'
private Expression parseSubstringSuffix(int start, Expression receiver) {
Expression startExpr;