diff options
author | 2017-08-14 12:00:51 +0200 | |
---|---|---|
committer | 2017-08-14 14:16:22 +0200 | |
commit | e0f1333de8e1ecd43bdb39992f97b916f00d49ee (patch) | |
tree | d768b73aee78b4c0f3aed0424c8a31a325aeae51 /src/main | |
parent | 05418b33dd87d63e2653e594d462b2aedb0e22e5 (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.java | 17 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/syntax/Parser.java | 41 |
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; |