in starlark/src/analysis/bind.rs [152:215]
fn stmt(x: &AstStmt, res: &mut Vec<Bind>) {
match &**x {
Stmt::Statements(xs) => {
for x in xs {
stmt(x, res)
}
}
Stmt::Break | Stmt::Continue | Stmt::Return(None) => flow(res),
Stmt::Pass => {}
Stmt::Return(Some(x)) => {
expr(x, res);
flow(res)
}
Stmt::Expression(x) => expr(x, res),
Stmt::If(a, box b) => {
expr(a, res);
flow(res);
stmt(b, res);
flow(res);
}
Stmt::IfElse(a, box (b, c)) => {
expr(a, res);
flow(res);
stmt(b, res);
flow(res);
stmt(c, res);
flow(res);
}
Stmt::Def(name, args, ret, body, _payload) => {
opt_expr(ret.as_ref().map(|x| &**x), res);
let mut inner = Vec::new();
parameters(args, res, &mut inner);
res.push(Bind::Set(Assigner::Assign, name.clone()));
stmt(body, &mut inner);
res.push(Bind::Scope(Scope::new(inner)));
}
Stmt::Assign(lhs, rhs) => {
expr(rhs, res);
expr_lvalue(lhs, res);
}
Stmt::AssignModify(lhs, _, rhs) => {
// For a += b, we:
// 1. Evaluate all variables and expressions in a.
// 2. Evaluate b.
// 3. Assign to all variables in a.
lhs.visit_expr(|x| expr(x, res));
lhs.visit_lvalue(|x| res.push(Bind::Get(x.clone().into_map(|AssignIdentP(s, ())| s))));
expr(rhs, res);
expr_lvalue(lhs, res);
}
Stmt::For(dest, box (inner, body)) => {
expr(inner, res);
expr_lvalue(dest, res);
flow(res);
stmt(body, res);
flow(res)
}
Stmt::Load(load) => {
for x in &load.node.args {
res.push(Bind::Set(Assigner::Load, x.0.clone()))
}
}
}
}