diff --git a/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java index 931d12c4aa12d2..8cbffe8e6fef90 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java @@ -25,19 +25,23 @@ public final class IfStatement extends Statement { private final Expression condition; // These blocks may be non-null but empty after a misparse: private final ImmutableList thenBlock; // non-empty - @Nullable ImmutableList elseBlock; // non-empty if non-null; set after construction + + @Nullable + final ImmutableList elseBlock; // non-empty if non-null; set after construction IfStatement( FileLocations locs, TokenKind token, int ifOffset, Expression condition, - List thenBlock) { + List thenBlock, + @Nullable List elseBlock) { super(locs); this.token = token; this.ifOffset = ifOffset; this.condition = condition; this.thenBlock = ImmutableList.copyOf(thenBlock); + this.elseBlock = elseBlock != null ? ImmutableList.copyOf(elseBlock) : null; } /** @@ -63,10 +67,6 @@ public ImmutableList getElseBlock() { return elseBlock; } - void setElseBlock(List elseBlock) { - this.elseBlock = ImmutableList.copyOf(elseBlock); - } - @Override public int getStartOffset() { return ifOffset; 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 1627df31e93c8e..5db54e759cb061 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 @@ -1118,24 +1118,37 @@ private IfStatement parseIfStatement() { Expression cond = parseTest(); expect(TokenKind.COLON); List body = parseSuite(); - IfStatement ifStmt = new IfStatement(locs, TokenKind.IF, ifOffset, cond, body); - IfStatement tail = ifStmt; + + ArrayList elifOffsets = new ArrayList<>(); + ArrayList elifConditions = new ArrayList<>(); + ArrayList> elifBodies = new ArrayList<>(); + while (token.kind == TokenKind.ELIF) { - int elifOffset = expect(TokenKind.ELIF); - cond = parseTest(); + elifOffsets.add(expect(TokenKind.ELIF)); + elifConditions.add(parseTest()); expect(TokenKind.COLON); - body = parseSuite(); - IfStatement elif = new IfStatement(locs, TokenKind.ELIF, elifOffset, cond, body); - tail.setElseBlock(ImmutableList.of(elif)); - tail = elif; + elifBodies.add(parseSuite()); } + + List tail; if (token.kind == TokenKind.ELSE) { expect(TokenKind.ELSE); expect(TokenKind.COLON); - body = parseSuite(); - tail.setElseBlock(body); + tail = parseSuite(); + } else { + tail = null; } - return ifStmt; + + for (int i = elifOffsets.size() - 1; i >= 0; --i) { + int elifOffset = elifOffsets.get(i); + Expression elifCondition = elifConditions.get(i); + List elifThenBlock = elifBodies.get(i); + IfStatement elif = + new IfStatement(locs, TokenKind.ELIF, elifOffset, elifCondition, elifThenBlock, tail); + tail = ImmutableList.of(elif); + } + + return new IfStatement(locs, TokenKind.IF, ifOffset, cond, body, tail); } // for_stmt = FOR IDENTIFIER IN expr ':' suite