aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main
diff options
context:
space:
mode:
authorGravatar fzaiser <fzaiser@google.com>2017-09-26 06:01:30 -0400
committerGravatar John Cater <jcater@google.com>2017-09-26 09:30:14 -0400
commitaa8540d6ee2189f991a13b4c4bea375b56cb4526 (patch)
tree687a52133a26e3c97a6f44afe3024fd59d401f41 /src/main
parentd16a067ae3c405e094c149a9e8452840f2da8567 (diff)
Fix end offset of expressions in Skylark parser
This CL doesn't fix all of the problems. The end location of blocks after an if, elif, else and for is still wrong. (I added TODOs for them) The latter is not easy to fix: One might think that one could just set the end location of a block to the end location of the last statement. However, if the last statement is a "pass" statement, this is not preserved in the AST, in particular, there's no location for it. In the future, we probably want to preserve "pass" statements. RELNOTES: none PiperOrigin-RevId: 170028466
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/Parser.java46
1 files changed, 28 insertions, 18 deletions
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 b25f89be19..979c63b4e3 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
@@ -500,7 +500,7 @@ public class Parser {
expect(TokenKind.DOT);
if (token.kind == TokenKind.IDENTIFIER) {
Identifier ident = parseIdent();
- return setLocation(new DotExpression(receiver, ident), start, token.right);
+ return setLocation(new DotExpression(receiver, ident), start, ident);
} else {
syntaxError(token, "expected identifier after dot");
int end = syncTo(EXPR_TERMINATOR_SET);
@@ -677,15 +677,18 @@ public class Parser {
}
// This is an index/key access
if (token.kind == TokenKind.RBRACKET) {
+ Expression expr = setLocation(new IndexExpression(receiver, startExpr), start, token.right);
expect(TokenKind.RBRACKET);
- return setLocation(new IndexExpression(receiver, startExpr), start, token.right);
+ return expr;
}
// This is a slice (or substring)
Expression endExpr = parseSliceArgument(new Identifier("None"));
Expression stepExpr = parseSliceArgument(new IntegerLiteral(1));
+ Expression expr =
+ setLocation(
+ new SliceExpression(receiver, startExpr, endExpr, stepExpr), start, token.right);
expect(TokenKind.RBRACKET);
- return setLocation(new SliceExpression(receiver, startExpr, endExpr, stepExpr),
- start, token.right);
+ return expr;
}
/**
@@ -735,14 +738,16 @@ public class Parser {
}
tuple.add(parsePrimaryWithSuffix());
}
- return setLocation(ListLiteral.makeTuple(tuple), start, token.right);
+ return setLocation(ListLiteral.makeTuple(tuple), start, Iterables.getLast(tuple));
}
// comprehension_suffix ::= 'FOR' loop_variables 'IN' expr comprehension_suffix
// | 'IF' expr comprehension_suffix
// | ']'
private Expression parseComprehensionSuffix(
- AbstractComprehension.AbstractBuilder comprehensionBuilder, TokenKind closingBracket) {
+ AbstractComprehension.AbstractBuilder comprehensionBuilder,
+ TokenKind closingBracket,
+ int comprehensionStartOffset) {
while (true) {
if (token.kind == TokenKind.FOR) {
nextToken();
@@ -758,12 +763,14 @@ public class Parser {
// [x for x in li if (1, 2)] # ok
comprehensionBuilder.addIf(parseNonTupleExpression(0));
} else if (token.kind == closingBracket) {
+ Expression expr = comprehensionBuilder.build();
+ setLocation(expr, comprehensionStartOffset, token.right);
nextToken();
- return comprehensionBuilder.build();
+ return expr;
} else {
syntaxError(token, "expected '" + closingBracket.getPrettyName() + "', 'for' or 'if'");
syncPast(LIST_TERMINATOR_SET);
- return makeErrorExpression(token.left, token.right);
+ return makeErrorExpression(comprehensionStartOffset, token.right);
}
}
}
@@ -794,11 +801,10 @@ public class Parser {
}
case FOR:
{ // list comprehension
- Expression result =
- parseComprehensionSuffix(
- new ListComprehension.Builder().setOutputExpression(expression),
- TokenKind.RBRACKET);
- return setLocation(result, start, token.right);
+ return parseComprehensionSuffix(
+ new ListComprehension.Builder().setOutputExpression(expression),
+ TokenKind.RBRACKET,
+ start);
}
case COMMA:
{
@@ -843,12 +849,12 @@ public class Parser {
DictionaryEntryLiteral entry = parseDictEntry();
if (token.kind == TokenKind.FOR) {
// Dict comprehension
- Expression result = parseComprehensionSuffix(
+ return parseComprehensionSuffix(
new DictComprehension.Builder()
.setKeyExpression(entry.getKey())
.setValueExpression(entry.getValue()),
- TokenKind.RBRACE);
- return setLocation(result, start, token.right);
+ TokenKind.RBRACE,
+ start);
}
List<DictionaryEntryLiteral> entries = new ArrayList<>();
entries.add(entry);
@@ -959,7 +965,7 @@ public class Parser {
// It's a tuple
List<Expression> tuple = parseExprList(insideParens);
tuple.add(0, expression); // add the first expression to the front of the tuple
- return setLocation(ListLiteral.makeTuple(tuple), start, token.right);
+ return setLocation(ListLiteral.makeTuple(tuple), start, Iterables.getLast(tuple));
}
// Equivalent to 'test' rule in Python grammar.
@@ -1000,7 +1006,7 @@ public class Parser {
Expression expression = parseNonTupleExpression(prec + 1);
UnaryOperatorExpression notExpression =
new UnaryOperatorExpression(UnaryOperator.NOT, expression);
- return setLocation(notExpression, start, token.right);
+ return setLocation(notExpression, start, expression);
}
// file_input ::= ('\n' | stmt)* EOF
@@ -1187,6 +1193,7 @@ public class Parser {
} else {
elseBlock = ImmutableList.of();
}
+ // TODO(skylark-team): the end offset should be the *previous* token, not the current one.
return setLocation(new IfStatement(thenBlocks, elseBlock), start, token.right);
}
@@ -1198,6 +1205,7 @@ public class Parser {
expect(TokenKind.COLON);
List<Statement> thenBlock = parseSuite();
ConditionalStatements stmt = new ConditionalStatements(expr, thenBlock);
+ // TODO(skylark-team): the end offset should be the *previous* token, not the current one.
return setLocation(stmt, start, token.right);
}
@@ -1211,6 +1219,7 @@ public class Parser {
expect(TokenKind.COLON);
List<Statement> block = parseSuite();
Statement stmt = new ForStatement(new LValue(loopVar), collection, block);
+ // TODO(skylark-team): the end offset should be the *previous* token, not the current one.
list.add(setLocation(stmt, start, token.right));
}
@@ -1227,6 +1236,7 @@ public class Parser {
expect(TokenKind.COLON);
List<Statement> block = parseSuite();
FunctionDefStatement stmt = new FunctionDefStatement(ident, params, signature, block);
+ // TODO(skylark-team): the end offset should be the *previous* token, not the current one.
list.add(setLocation(stmt, start, token.right));
}