1use serde::Serialize;
2
3use crate::Span;
4
5use super::{
6 ArenaVec, Attribute, ClassDecl, Comment, EnumDecl, Expr, FunctionDecl, Ident, InterfaceDecl,
7 Name, TraitDecl,
8};
9
10fn is_false(b: &bool) -> bool {
11 !b
12}
13
14#[derive(Debug, Serialize)]
15pub struct Stmt<'arena, 'src> {
16 pub kind: StmtKind<'arena, 'src>,
17 pub span: Span,
18}
19
20#[derive(Debug, Serialize)]
21pub enum StmtKind<'arena, 'src> {
22 Expression(&'arena Expr<'arena, 'src>),
24
25 Echo(ArenaVec<'arena, Expr<'arena, 'src>>),
27
28 Return(Option<&'arena Expr<'arena, 'src>>),
30
31 Block(ArenaVec<'arena, Stmt<'arena, 'src>>),
33
34 If(&'arena IfStmt<'arena, 'src>),
36
37 While(&'arena WhileStmt<'arena, 'src>),
39
40 For(&'arena ForStmt<'arena, 'src>),
42
43 Foreach(&'arena ForeachStmt<'arena, 'src>),
45
46 DoWhile(&'arena DoWhileStmt<'arena, 'src>),
48
49 Function(&'arena FunctionDecl<'arena, 'src>),
51
52 Break(Option<&'arena Expr<'arena, 'src>>),
54
55 Continue(Option<&'arena Expr<'arena, 'src>>),
57
58 Switch(&'arena SwitchStmt<'arena, 'src>),
60
61 Goto(Ident<'src>),
63
64 Label(&'arena str),
66
67 Declare(&'arena DeclareStmt<'arena, 'src>),
69
70 Unset(ArenaVec<'arena, Expr<'arena, 'src>>),
72
73 Throw(&'arena Expr<'arena, 'src>),
75
76 TryCatch(&'arena TryCatchStmt<'arena, 'src>),
78
79 Global(ArenaVec<'arena, Expr<'arena, 'src>>),
81
82 Class(&'arena ClassDecl<'arena, 'src>),
84
85 Interface(&'arena InterfaceDecl<'arena, 'src>),
87
88 Trait(&'arena TraitDecl<'arena, 'src>),
90
91 Enum(&'arena EnumDecl<'arena, 'src>),
93
94 Namespace(&'arena NamespaceDecl<'arena, 'src>),
96
97 Use(&'arena UseDecl<'arena, 'src>),
99
100 Const(ArenaVec<'arena, ConstItem<'arena, 'src>>),
102
103 StaticVar(ArenaVec<'arena, StaticVar<'arena, 'src>>),
105
106 HaltCompiler(&'src str),
108
109 Nop,
111
112 InlineHtml(&'src str),
114
115 Error,
117}
118
119#[derive(Debug, Serialize)]
120pub struct IfStmt<'arena, 'src> {
121 pub condition: Expr<'arena, 'src>,
122 pub then_branch: &'arena Stmt<'arena, 'src>,
123 pub elseif_branches: ArenaVec<'arena, ElseIfBranch<'arena, 'src>>,
124 pub else_branch: Option<&'arena Stmt<'arena, 'src>>,
125 #[serde(default, skip_serializing_if = "is_false")]
126 pub uses_alternative: bool,
127}
128
129#[derive(Debug, Serialize)]
130pub struct ElseIfBranch<'arena, 'src> {
131 pub condition: Expr<'arena, 'src>,
132 pub body: Stmt<'arena, 'src>,
133 pub span: Span,
134}
135
136#[derive(Debug, Serialize)]
137pub struct WhileStmt<'arena, 'src> {
138 pub condition: Expr<'arena, 'src>,
139 pub body: &'arena Stmt<'arena, 'src>,
140 #[serde(default, skip_serializing_if = "is_false")]
141 pub uses_alternative: bool,
142}
143
144#[derive(Debug, Serialize)]
145pub struct ForStmt<'arena, 'src> {
146 pub init: ArenaVec<'arena, Expr<'arena, 'src>>,
147 pub condition: ArenaVec<'arena, Expr<'arena, 'src>>,
148 pub update: ArenaVec<'arena, Expr<'arena, 'src>>,
149 pub body: &'arena Stmt<'arena, 'src>,
150 #[serde(default, skip_serializing_if = "is_false")]
151 pub uses_alternative: bool,
152}
153
154#[derive(Debug, Serialize)]
155pub struct ForeachStmt<'arena, 'src> {
156 pub expr: Expr<'arena, 'src>,
157 pub key: Option<Expr<'arena, 'src>>,
158 pub value: Expr<'arena, 'src>,
159 pub body: &'arena Stmt<'arena, 'src>,
160 #[serde(default, skip_serializing_if = "is_false")]
161 pub uses_alternative: bool,
162}
163
164#[derive(Debug, Serialize)]
165pub struct DoWhileStmt<'arena, 'src> {
166 pub body: &'arena Stmt<'arena, 'src>,
167 pub condition: Expr<'arena, 'src>,
168}
169
170#[derive(Debug, Serialize)]
171pub struct SwitchStmt<'arena, 'src> {
172 pub expr: Expr<'arena, 'src>,
173 pub cases: ArenaVec<'arena, SwitchCase<'arena, 'src>>,
174 #[serde(default, skip_serializing_if = "is_false")]
175 pub uses_alternative: bool,
176}
177
178#[derive(Debug, Serialize)]
179pub struct SwitchCase<'arena, 'src> {
180 pub value: Option<Expr<'arena, 'src>>,
181 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
182 pub span: Span,
183}
184
185#[derive(Debug, Serialize)]
186pub struct TryCatchStmt<'arena, 'src> {
187 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
188 pub catches: ArenaVec<'arena, CatchClause<'arena, 'src>>,
189 pub finally: Option<ArenaVec<'arena, Stmt<'arena, 'src>>>,
190}
191
192#[derive(Debug, Serialize)]
193pub struct CatchClause<'arena, 'src> {
194 pub types: ArenaVec<'arena, Name<'arena, 'src>>,
195 pub var: Option<&'src str>,
196 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
197 pub span: Span,
198}
199
200#[derive(Debug, Serialize)]
201pub struct NamespaceDecl<'arena, 'src> {
202 pub name: Option<Name<'arena, 'src>>,
203 pub body: NamespaceBody<'arena, 'src>,
204}
205
206#[derive(Debug, Serialize)]
207pub enum NamespaceBody<'arena, 'src> {
208 Braced(ArenaVec<'arena, Stmt<'arena, 'src>>),
210 Simple,
212}
213
214#[derive(Debug, Serialize)]
215pub struct DeclareStmt<'arena, 'src> {
216 pub directives: ArenaVec<'arena, (&'src str, Expr<'arena, 'src>)>,
217 pub body: Option<&'arena Stmt<'arena, 'src>>,
218 #[serde(default, skip_serializing_if = "is_false")]
219 pub uses_alternative: bool,
220}
221
222#[derive(Debug, Serialize)]
223pub struct UseDecl<'arena, 'src> {
224 pub kind: UseKind,
225 pub uses: ArenaVec<'arena, UseItem<'arena, 'src>>,
226}
227
228#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
229pub enum UseKind {
230 Normal,
232 Function,
234 Const,
236}
237
238#[derive(Debug, Serialize)]
239pub struct UseItem<'arena, 'src> {
240 pub name: Name<'arena, 'src>,
241 pub alias: Option<&'src str>,
242 #[serde(skip_serializing_if = "Option::is_none")]
243 pub kind: Option<UseKind>,
244 pub span: Span,
245}
246
247#[derive(Debug, Serialize)]
248pub struct ConstItem<'arena, 'src> {
249 pub name: Ident<'src>,
250 pub value: Expr<'arena, 'src>,
251 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
252 pub span: Span,
253 #[serde(skip_serializing_if = "Option::is_none")]
254 pub doc_comment: Option<Comment<'src>>,
255}
256
257#[derive(Debug, Serialize)]
258pub struct StaticVar<'arena, 'src> {
259 pub name: Ident<'src>,
260 pub default: Option<Expr<'arena, 'src>>,
261 pub span: Span,
262}