solar_ast/ast/stmt.rs
1use crate::{
2 AstPath, Box, BoxSlice, CallArgs, DocComments, Expr, ParameterList, StrLit, VariableDefinition,
3 yul,
4};
5use solar_interface::{Ident, Span, SpannedOption};
6
7/// A block of statements.
8#[derive(Debug)]
9pub struct Block<'ast> {
10 /// The span of the block, including the `{` and `}`.
11 pub span: Span,
12 /// The statements in the block.
13 pub stmts: BoxSlice<'ast, Stmt<'ast>>,
14}
15
16impl<'ast> std::ops::Deref for Block<'ast> {
17 type Target = [Stmt<'ast>];
18
19 fn deref(&self) -> &Self::Target {
20 self.stmts
21 }
22}
23
24impl<'ast> std::ops::DerefMut for Block<'ast> {
25 fn deref_mut(&mut self) -> &mut Self::Target {
26 self.stmts
27 }
28}
29
30/// A statement, usually ending in a semicolon.
31///
32/// Reference: <https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.statement>
33#[derive(Debug)]
34pub struct Stmt<'ast> {
35 pub docs: DocComments<'ast>,
36 pub span: Span,
37 pub kind: StmtKind<'ast>,
38}
39
40/// A kind of statement.
41#[derive(Debug)]
42pub enum StmtKind<'ast> {
43 /// An assembly block, with optional flags: `assembly "evmasm" (...) { ... }`.
44 Assembly(StmtAssembly<'ast>),
45
46 /// A single-variable declaration statement: `uint256 foo = 42;`.
47 DeclSingle(Box<'ast, VariableDefinition<'ast>>),
48
49 /// A multi-variable declaration statement: `(bool success, bytes memory value) = ...;`.
50 ///
51 /// Multi-assignments require an expression on the right-hand side.
52 DeclMulti(BoxSlice<'ast, SpannedOption<VariableDefinition<'ast>>>, Box<'ast, Expr<'ast>>),
53
54 /// A blocked scope: `{ ... }`.
55 Block(Block<'ast>),
56
57 /// A break statement: `break;`.
58 Break,
59
60 /// A continue statement: `continue;`.
61 Continue,
62
63 /// A do-while statement: `do { ... } while (condition);`.
64 DoWhile(Box<'ast, Stmt<'ast>>, Box<'ast, Expr<'ast>>),
65
66 /// An emit statement: `emit Foo.bar(42);`.
67 Emit(AstPath<'ast>, CallArgs<'ast>),
68
69 /// An expression with a trailing semicolon.
70 Expr(Box<'ast, Expr<'ast>>),
71
72 /// A for statement: `for (uint256 i; i < 42; ++i) { ... }`.
73 For {
74 init: Option<Box<'ast, Stmt<'ast>>>,
75 cond: Option<Box<'ast, Expr<'ast>>>,
76 next: Option<Box<'ast, Expr<'ast>>>,
77 body: Box<'ast, Stmt<'ast>>,
78 },
79
80 /// An `if` statement with an optional `else` block: `if (expr) { ... } else { ... }`.
81 If(Box<'ast, Expr<'ast>>, Box<'ast, Stmt<'ast>>, Option<Box<'ast, Stmt<'ast>>>),
82
83 /// A return statement: `return 42;`.
84 Return(Option<Box<'ast, Expr<'ast>>>),
85
86 /// A revert statement: `revert Foo.bar(42);`.
87 Revert(AstPath<'ast>, CallArgs<'ast>),
88
89 /// A try statement: `try fooBar(42) returns (...) { ... } catch (...) { ... }`.
90 Try(Box<'ast, StmtTry<'ast>>),
91
92 /// An unchecked block: `unchecked { ... }`.
93 UncheckedBlock(Block<'ast>),
94
95 /// A while statement: `while (i < 42) { ... }`.
96 While(Box<'ast, Expr<'ast>>, Box<'ast, Stmt<'ast>>),
97
98 /// A modifier placeholder statement: `_;`.
99 Placeholder,
100}
101
102/// An assembly block, with optional flags: `assembly "evmasm" (...) { ... }`.
103#[derive(Debug)]
104pub struct StmtAssembly<'ast> {
105 /// The assembly block dialect.
106 pub dialect: Option<StrLit>,
107 /// Additional flags.
108 pub flags: BoxSlice<'ast, StrLit>,
109 /// The assembly block.
110 pub block: yul::Block<'ast>,
111}
112
113/// A try statement: `try fooBar(42) returns (...) { ... } catch (...) { ... }`.
114///
115/// Reference: <https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.tryStatement>
116#[derive(Debug)]
117pub struct StmtTry<'ast> {
118 /// The call expression.
119 pub expr: Box<'ast, Expr<'ast>>,
120 /// The list of clauses. Never empty.
121 pub clauses: BoxSlice<'ast, TryCatchClause<'ast>>,
122}
123
124/// Clause of a try/catch block: `returns/catch (...) { ... }`.
125///
126/// Includes both the successful case and the unsuccessful cases.
127/// Names are only allowed for unsuccessful cases.
128///
129/// Reference: <https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.catchClause>
130#[derive(Debug)]
131pub struct TryCatchClause<'ast> {
132 /// The span of the entire clause, from the `returns` and `catch`
133 /// keywords, to the closing brace of the block.
134 pub span: Span,
135 /// The catch clause name: `Error`, `Panic`, or custom.
136 pub name: Option<Ident>,
137 /// The parameter list for the clause.
138 pub args: ParameterList<'ast>,
139 /// A block of statements
140 pub block: Block<'ast>,
141}