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)]
26#[serde(transparent)]
27pub struct Block<'arena, 'src> {
28 pub stmts: ArenaVec<'arena, Stmt<'arena, 'src>>,
29 #[serde(skip)]
32 pub span: Span,
33}
34
35#[derive(Debug, Serialize)]
36pub enum StmtKind<'arena, 'src> {
37 Expression(&'arena Expr<'arena, 'src>),
39
40 Echo(ArenaVec<'arena, Expr<'arena, 'src>>),
42
43 Return(Option<&'arena Expr<'arena, 'src>>),
45
46 Block(&'arena Block<'arena, 'src>),
48
49 If(&'arena IfStmt<'arena, 'src>),
51
52 While(&'arena WhileStmt<'arena, 'src>),
54
55 For(&'arena ForStmt<'arena, 'src>),
57
58 Foreach(&'arena ForeachStmt<'arena, 'src>),
60
61 DoWhile(&'arena DoWhileStmt<'arena, 'src>),
63
64 Function(&'arena FunctionDecl<'arena, 'src>),
66
67 Break(Option<&'arena Expr<'arena, 'src>>),
69
70 Continue(Option<&'arena Expr<'arena, 'src>>),
72
73 Switch(&'arena SwitchStmt<'arena, 'src>),
75
76 Goto(Ident<'src>),
78
79 Label(&'arena str),
81
82 Declare(&'arena DeclareStmt<'arena, 'src>),
84
85 Unset(ArenaVec<'arena, Expr<'arena, 'src>>),
87
88 Throw(&'arena Expr<'arena, 'src>),
90
91 TryCatch(&'arena TryCatchStmt<'arena, 'src>),
93
94 Global(ArenaVec<'arena, Expr<'arena, 'src>>),
96
97 Class(&'arena ClassDecl<'arena, 'src>),
99
100 Interface(&'arena InterfaceDecl<'arena, 'src>),
102
103 Trait(&'arena TraitDecl<'arena, 'src>),
105
106 Enum(&'arena EnumDecl<'arena, 'src>),
108
109 Namespace(&'arena NamespaceDecl<'arena, 'src>),
111
112 Use(&'arena UseDecl<'arena, 'src>),
114
115 Const(ArenaVec<'arena, ConstItem<'arena, 'src>>),
117
118 StaticVar(ArenaVec<'arena, StaticVar<'arena, 'src>>),
120
121 HaltCompiler(&'src str),
123
124 Nop,
126
127 InlineHtml(&'src str),
129
130 Error,
132}
133
134#[derive(Debug, Serialize)]
135pub struct IfStmt<'arena, 'src> {
136 pub condition: Expr<'arena, 'src>,
137 pub then_branch: &'arena Stmt<'arena, 'src>,
138 pub elseif_branches: ArenaVec<'arena, ElseIfBranch<'arena, 'src>>,
139 pub else_branch: Option<&'arena Stmt<'arena, 'src>>,
140 #[serde(skip)]
142 pub else_kw_start: Option<u32>,
143 #[serde(default, skip_serializing_if = "is_false")]
144 pub uses_alternative: bool,
145}
146
147#[derive(Debug, Serialize)]
148pub struct ElseIfBranch<'arena, 'src> {
149 pub condition: Expr<'arena, 'src>,
150 pub body: Stmt<'arena, 'src>,
151 pub span: Span,
152}
153
154#[derive(Debug, Serialize)]
155pub struct WhileStmt<'arena, 'src> {
156 pub condition: Expr<'arena, 'src>,
157 pub body: &'arena Stmt<'arena, 'src>,
158 #[serde(default, skip_serializing_if = "is_false")]
159 pub uses_alternative: bool,
160}
161
162#[derive(Debug, Serialize)]
163pub struct ForStmt<'arena, 'src> {
164 pub init: ArenaVec<'arena, Expr<'arena, 'src>>,
165 pub condition: ArenaVec<'arena, Expr<'arena, 'src>>,
166 pub update: ArenaVec<'arena, Expr<'arena, 'src>>,
167 pub body: &'arena Stmt<'arena, 'src>,
168 #[serde(default, skip_serializing_if = "is_false")]
169 pub uses_alternative: bool,
170}
171
172#[derive(Debug, Serialize)]
173pub struct ForeachStmt<'arena, 'src> {
174 pub expr: Expr<'arena, 'src>,
175 pub key: Option<Expr<'arena, 'src>>,
176 pub value: Expr<'arena, 'src>,
177 pub body: &'arena Stmt<'arena, 'src>,
178 #[serde(default, skip_serializing_if = "is_false")]
179 pub uses_alternative: bool,
180}
181
182#[derive(Debug, Serialize)]
183pub struct DoWhileStmt<'arena, 'src> {
184 pub body: &'arena Stmt<'arena, 'src>,
185 pub condition: Expr<'arena, 'src>,
186}
187
188#[derive(Debug, Serialize)]
189pub struct SwitchBody<'arena, 'src> {
190 pub cases: ArenaVec<'arena, SwitchCase<'arena, 'src>>,
191 #[serde(skip)]
192 pub span: Span,
193}
194
195#[derive(Debug, Serialize)]
196pub struct SwitchStmt<'arena, 'src> {
197 pub expr: Expr<'arena, 'src>,
198 #[serde(flatten)]
199 pub body: SwitchBody<'arena, 'src>,
200 #[serde(default, skip_serializing_if = "is_false")]
201 pub uses_alternative: bool,
202}
203
204#[derive(Debug, Serialize)]
205pub struct SwitchCase<'arena, 'src> {
206 pub value: Option<Expr<'arena, 'src>>,
207 pub body: ArenaVec<'arena, Stmt<'arena, 'src>>,
208 pub span: Span,
209}
210
211#[derive(Debug, Serialize)]
212pub struct TryCatchStmt<'arena, 'src> {
213 pub body: &'arena Block<'arena, 'src>,
214 pub catches: ArenaVec<'arena, CatchClause<'arena, 'src>>,
215 pub finally: Option<&'arena Block<'arena, 'src>>,
216 #[serde(skip)]
218 pub finally_kw_start: Option<u32>,
219}
220
221#[derive(Debug, Serialize)]
222pub struct CatchClause<'arena, 'src> {
223 pub types: ArenaVec<'arena, Name<'arena, 'src>>,
224 pub var: Option<&'src str>,
225 pub body: &'arena Block<'arena, 'src>,
226 pub span: Span,
227}
228
229#[derive(Debug, Serialize)]
230pub struct NamespaceDecl<'arena, 'src> {
231 pub name: Option<Name<'arena, 'src>>,
232 pub body: NamespaceBody<'arena, 'src>,
233}
234
235#[derive(Debug, Serialize)]
236pub enum NamespaceBody<'arena, 'src> {
237 Braced(&'arena Block<'arena, 'src>),
239 Simple,
241}
242
243#[derive(Debug, Serialize)]
244pub struct DeclareStmt<'arena, 'src> {
245 pub directives: ArenaVec<'arena, (&'src str, Expr<'arena, 'src>)>,
246 pub body: Option<&'arena Stmt<'arena, 'src>>,
247 #[serde(default, skip_serializing_if = "is_false")]
248 pub uses_alternative: bool,
249}
250
251#[derive(Debug, Serialize)]
252pub struct UseDecl<'arena, 'src> {
253 pub kind: UseKind,
254 pub uses: ArenaVec<'arena, UseItem<'arena, 'src>>,
255}
256
257#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
258pub enum UseKind {
259 Normal,
261 Function,
263 Const,
265}
266
267#[derive(Debug, Serialize)]
268pub struct UseItem<'arena, 'src> {
269 pub name: Name<'arena, 'src>,
270 pub alias: Option<&'src str>,
271 #[serde(skip_serializing_if = "Option::is_none")]
272 pub kind: Option<UseKind>,
273 pub span: Span,
274}
275
276#[derive(Debug, Serialize)]
277pub struct ConstItem<'arena, 'src> {
278 pub name: Ident<'src>,
279 pub value: Expr<'arena, 'src>,
280 pub attributes: ArenaVec<'arena, Attribute<'arena, 'src>>,
281 pub span: Span,
282 #[serde(skip_serializing_if = "Option::is_none")]
283 pub doc_comment: Option<Comment<'src>>,
284}
285
286#[derive(Debug, Serialize)]
287pub struct StaticVar<'arena, 'src> {
288 pub name: Ident<'src>,
289 pub default: Option<Expr<'arena, 'src>>,
290 pub span: Span,
291}