Skip to main content

solidity_language_server/solc_ast/
statements.rs

1//! Statement AST node types.
2//!
3//! Corresponds to the statement hierarchy in the official solc AST.
4
5use serde::{Deserialize, Serialize};
6
7use super::{Expression, NodeID, VariableDeclaration};
8
9/// The union of all statement node types.
10///
11/// Discriminated by `nodeType` in the JSON.
12#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
13#[serde(tag = "nodeType")]
14pub enum Statement {
15    Block(Block),
16    UncheckedBlock(UncheckedBlock),
17    PlaceholderStatement(PlaceholderStatement),
18    IfStatement(IfStatement),
19    WhileStatement(WhileStatement),
20    DoWhileStatement(DoWhileStatement),
21    ForStatement(ForStatement),
22    Continue(Continue),
23    Break(Break),
24    Return(Return),
25    Throw(Throw),
26    EmitStatement(EmitStatement),
27    RevertStatement(RevertStatement),
28    VariableDeclarationStatement(VariableDeclarationStatement),
29    ExpressionStatement(ExpressionStatement),
30    TryStatement(TryStatement),
31    InlineAssembly(InlineAssembly),
32}
33
34/// A block of statements (`{ ... }`).
35#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
36#[serde(rename_all = "camelCase")]
37pub struct Block {
38    pub id: NodeID,
39    pub src: String,
40    #[serde(default)]
41    pub statements: Vec<Statement>,
42}
43
44/// An `unchecked { ... }` block.
45#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
46#[serde(rename_all = "camelCase")]
47pub struct UncheckedBlock {
48    pub id: NodeID,
49    pub src: String,
50    #[serde(default)]
51    pub statements: Vec<Statement>,
52}
53
54/// A placeholder statement (`_`) inside a modifier body.
55#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
56#[serde(rename_all = "camelCase")]
57pub struct PlaceholderStatement {
58    pub id: NodeID,
59    pub src: String,
60}
61
62/// An `if` statement.
63#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
64#[serde(rename_all = "camelCase")]
65pub struct IfStatement {
66    pub id: NodeID,
67    pub src: String,
68    pub condition: Expression,
69    pub true_body: Box<Statement>,
70    pub false_body: Option<Box<Statement>>,
71}
72
73/// A `while` statement.
74#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
75#[serde(rename_all = "camelCase")]
76pub struct WhileStatement {
77    pub id: NodeID,
78    pub src: String,
79    pub condition: Expression,
80    pub body: Box<Statement>,
81}
82
83/// A `do { ... } while (...)` statement.
84///
85/// The JSON exporter emits `"nodeType": "DoWhileStatement"` for do-while loops.
86#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
87#[serde(rename_all = "camelCase")]
88pub struct DoWhileStatement {
89    pub id: NodeID,
90    pub src: String,
91    pub condition: Expression,
92    pub body: Box<Statement>,
93}
94
95/// A `for` statement.
96#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
97#[serde(rename_all = "camelCase")]
98pub struct ForStatement {
99    pub id: NodeID,
100    pub src: String,
101    pub initialization_expression: Option<Box<Statement>>,
102    pub condition: Option<Expression>,
103    pub loop_expression: Option<Box<Statement>>,
104    pub body: Box<Statement>,
105    #[serde(default)]
106    pub is_simple_counter_loop: Option<bool>,
107}
108
109/// A `continue` statement.
110#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
111#[serde(rename_all = "camelCase")]
112pub struct Continue {
113    pub id: NodeID,
114    pub src: String,
115}
116
117/// A `break` statement.
118#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
119#[serde(rename_all = "camelCase")]
120pub struct Break {
121    pub id: NodeID,
122    pub src: String,
123}
124
125/// A `return` statement.
126#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
127#[serde(rename_all = "camelCase")]
128pub struct Return {
129    pub id: NodeID,
130    pub src: String,
131    #[serde(default)]
132    pub expression: Option<Expression>,
133    pub function_return_parameters: Option<NodeID>,
134}
135
136/// A `throw` statement (deprecated, pre-0.5).
137#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
138#[serde(rename_all = "camelCase")]
139pub struct Throw {
140    pub id: NodeID,
141    pub src: String,
142}
143
144/// An `emit` statement.
145#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
146#[serde(rename_all = "camelCase")]
147pub struct EmitStatement {
148    pub id: NodeID,
149    pub src: String,
150    pub event_call: Expression,
151}
152
153/// A `revert` statement.
154#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
155#[serde(rename_all = "camelCase")]
156pub struct RevertStatement {
157    pub id: NodeID,
158    pub src: String,
159    pub error_call: Expression,
160}
161
162/// A variable declaration statement (`uint256 x = 42;`).
163#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
164#[serde(rename_all = "camelCase")]
165pub struct VariableDeclarationStatement {
166    pub id: NodeID,
167    pub src: String,
168    /// Node IDs of the declared variables (may contain `null` for tuple destructuring).
169    #[serde(default)]
170    pub assignments: Vec<Option<NodeID>>,
171    /// The variable declaration nodes.
172    #[serde(default)]
173    pub declarations: Vec<Option<VariableDeclaration>>,
174    /// Initial value expression.
175    pub initial_value: Option<Expression>,
176}
177
178/// An expression statement (a bare expression used as a statement).
179#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
180#[serde(rename_all = "camelCase")]
181pub struct ExpressionStatement {
182    pub id: NodeID,
183    pub src: String,
184    pub expression: Expression,
185    /// Rarely present; only when the expression statement has documentation.
186    #[serde(default)]
187    pub documentation: Option<String>,
188}
189
190/// A `try` statement.
191#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
192#[serde(rename_all = "camelCase")]
193pub struct TryStatement {
194    pub id: NodeID,
195    pub src: String,
196    pub external_call: Expression,
197    #[serde(default)]
198    pub clauses: Vec<TryCatchClause>,
199}
200
201/// A single `catch` clause in a `try` statement.
202#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
203#[serde(rename_all = "camelCase")]
204pub struct TryCatchClause {
205    pub id: NodeID,
206    pub src: String,
207    #[serde(default)]
208    pub error_name: Option<String>,
209    #[serde(default)]
210    pub parameters: Option<super::ParameterList>,
211    pub block: Block,
212}
213
214/// An inline assembly block.
215#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
216#[serde(rename_all = "camelCase")]
217pub struct InlineAssembly {
218    pub id: NodeID,
219    pub src: String,
220    /// The Yul AST root.
221    #[serde(rename = "AST", default)]
222    pub ast: Option<super::YulBlock>,
223    #[serde(default)]
224    pub external_references: Vec<super::ExternalReference>,
225    #[serde(default)]
226    pub evm_version: Option<String>,
227    #[serde(default)]
228    pub flags: Option<Vec<String>>,
229}