Skip to main content

gen_bazel/
ast.rs

1//! Minimal typed Starlark AST. Covers the subset BUILD files actually
2//! use: atoms, lists, dicts, function calls, named keyword args,
3//! load() statements, assignments. Full Starlark eval is out of
4//! scope — this is an emission AST only.
5
6/// One BUILD file statement.
7#[derive(Clone, Debug, PartialEq)]
8pub enum StarlarkStmt {
9    /// `load("@rules/foo.bzl", "sym1", "sym2", ...)`
10    Load {
11        module: String,
12        symbols: Vec<String>,
13    },
14    /// `func(arg1, arg2, kw=val, ...)`
15    Call {
16        func: String,
17        args: Vec<KwArg>,
18    },
19    /// `name = value`
20    Assign {
21        name: String,
22        value: StarlarkValue,
23    },
24}
25
26/// Argument to a Starlark call. Either positional or keyword. The
27/// positional_named variant attaches a name for renderer-side
28/// pretty-printing (`name = ...` form), used for the canonical
29/// kwarg-style every BUILD file actually authors.
30#[derive(Clone, Debug, PartialEq)]
31pub enum KwArg {
32    Positional(StarlarkValue),
33    Named { name: String, value: StarlarkValue },
34}
35
36impl KwArg {
37    pub fn str(name: &str, value: impl Into<String>) -> Self {
38        Self::Named {
39            name: name.to_string(),
40            value: StarlarkValue::Str(value.into()),
41        }
42    }
43    pub fn positional(value: StarlarkValue) -> Self {
44        Self::Positional(value)
45    }
46    pub fn positional_named(name: &str, value: StarlarkValue) -> Self {
47        Self::Named {
48            name: name.to_string(),
49            value,
50        }
51    }
52}
53
54#[derive(Clone, Debug, PartialEq)]
55pub enum StarlarkValue {
56    None,
57    Bool(bool),
58    Int(i64),
59    Str(String),
60    Ident(String),
61    List(Vec<StarlarkValue>),
62    Dict(Vec<(String, StarlarkValue)>),
63    Call { func: String, args: Vec<KwArg> },
64}
65
66impl StarlarkValue {
67    pub fn str(s: impl Into<String>) -> Self {
68        Self::Str(s.into())
69    }
70}