blob: 697923f264d45815000bb37684993ce5e6df743d [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.syntax;
15
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010016import com.google.common.collect.ImmutableList;
Mark Schaller6df81792015-12-10 18:47:47 +000017import com.google.devtools.build.lib.util.Preconditions;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010018import java.util.List;
19
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010020/**
21 * Syntax node for an if/else statement.
22 */
23public final class IfStatement extends Statement {
24
25 /**
26 * Syntax node for an [el]if statement.
27 */
28 static final class ConditionalStatements extends Statement {
29
30 private final Expression condition;
31 private final ImmutableList<Statement> stmts;
32
33 public ConditionalStatements(Expression condition, List<Statement> stmts) {
34 this.condition = Preconditions.checkNotNull(condition);
35 this.stmts = ImmutableList.copyOf(stmts);
36 }
37
38 @Override
Florian Weikert90a15962015-09-11 13:43:10 +000039 void doExec(Environment env) throws EvalException, InterruptedException {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010040 for (Statement stmt : stmts) {
41 stmt.exec(env);
42 }
43 }
44
45 @Override
46 public String toString() {
Francois-Rene Rideaucbebd632015-02-11 16:56:37 +000047 return "[el]if " + condition + ": " + stmts + "\n";
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010048 }
49
50 @Override
51 public void accept(SyntaxTreeVisitor visitor) {
52 visitor.visit(this);
53 }
54
55 Expression getCondition() {
56 return condition;
57 }
58
59 ImmutableList<Statement> getStmts() {
60 return stmts;
61 }
62
63 @Override
64 void validate(ValidationEnvironment env) throws EvalException {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010065 condition.validate(env);
66 validateStmts(env, stmts);
67 }
68 }
69
70 private final ImmutableList<ConditionalStatements> thenBlocks;
71 private final ImmutableList<Statement> elseBlock;
72
73 /**
74 * Constructs a if-elif-else statement. The else part is mandatory, but the list may be empty.
75 * ThenBlocks has to have at least one element.
76 */
77 IfStatement(List<ConditionalStatements> thenBlocks, List<Statement> elseBlock) {
Ulf Adams07dba942015-03-05 14:47:37 +000078 Preconditions.checkArgument(!thenBlocks.isEmpty());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010079 this.thenBlocks = ImmutableList.copyOf(thenBlocks);
80 this.elseBlock = ImmutableList.copyOf(elseBlock);
81 }
82
83 public ImmutableList<ConditionalStatements> getThenBlocks() {
84 return thenBlocks;
85 }
86
87 public ImmutableList<Statement> getElseBlock() {
88 return elseBlock;
89 }
90
91 @Override
92 public String toString() {
93 // TODO(bazel-team): if we want to print the complete statement, the function
94 // needs an extra argument to specify indentation level.
Florian Weikert90a15962015-09-11 13:43:10 +000095 // As guaranteed by the constructor, there must be at least one element in thenBlocks.
96 return String.format("if %s:\n", thenBlocks.get(0).getCondition());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010097 }
98
99 @Override
Florian Weikert90a15962015-09-11 13:43:10 +0000100 void doExec(Environment env) throws EvalException, InterruptedException {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100101 for (ConditionalStatements stmt : thenBlocks) {
102 if (EvalUtils.toBoolean(stmt.getCondition().eval(env))) {
103 stmt.exec(env);
104 return;
105 }
106 }
107 for (Statement stmt : elseBlock) {
108 stmt.exec(env);
109 }
110 }
111
112 @Override
113 public void accept(SyntaxTreeVisitor visitor) {
114 visitor.visit(this);
115 }
116
117 @Override
118 void validate(ValidationEnvironment env) throws EvalException {
119 env.startTemporarilyDisableReadonlyCheckSession();
120 for (ConditionalStatements stmts : thenBlocks) {
121 stmts.validate(env);
122 }
123 validateStmts(env, elseBlock);
124 env.finishTemporarilyDisableReadonlyCheckSession();
125 }
126
127 private static void validateStmts(ValidationEnvironment env, List<Statement> stmts)
128 throws EvalException {
129 for (Statement stmt : stmts) {
130 stmt.validate(env);
131 }
132 env.finishTemporarilyDisableReadonlyCheckBranch();
133 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100134}