1use std::sync::{Arc, RwLock, RwLockReadGuard};
22
23use derive_more::{From, IsVariant, Unwrap};
24
25pub use crate::span::{Span, Spanned};
26
27pub use wgsl_types::syntax::*;
28
29#[cfg(feature = "tokrepr")]
30use tokrepr::TokRepr;
31
32#[cfg(feature = "serde")]
33use serde::{Deserialize, Serialize};
34
35#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
36#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
37#[derive(Default, Clone, Debug, PartialEq)]
38pub struct TranslationUnit {
39 #[cfg(feature = "imports")]
40 pub imports: Vec<ImportStatement>,
41 pub global_directives: Vec<GlobalDirective>,
42 pub global_declarations: Vec<GlobalDeclarationNode>,
43}
44
45#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
52#[derive(Clone, Debug)]
53pub struct Ident(Arc<RwLock<String>>);
54
55impl Ident {
56 pub fn new(name: String) -> Ident {
58 Ident(Arc::new(RwLock::new(name)))
60 }
61 pub fn name(&self) -> RwLockReadGuard<'_, String> {
63 self.0.read().unwrap()
64 }
65 pub fn rename(&mut self, name: String) {
67 *self.0.write().unwrap() = name;
68 }
69 pub fn use_count(&self) -> usize {
71 Arc::<_>::strong_count(&self.0)
72 }
73}
74
75impl From<String> for Ident {
76 fn from(name: String) -> Self {
77 Ident::new(name)
78 }
79}
80
81impl PartialEq for Ident {
83 fn eq(&self, other: &Self) -> bool {
84 Arc::ptr_eq(&self.0, &other.0)
85 }
86}
87
88impl Eq for Ident {}
90
91impl std::hash::Hash for Ident {
93 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
94 std::ptr::hash(&*self.0, state)
95 }
96}
97
98#[cfg(feature = "imports")]
99#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
100#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
101#[derive(Clone, Debug, PartialEq)]
102pub struct ImportStatement {
103 #[cfg(feature = "attributes")]
104 pub attributes: Attributes,
105 pub path: Option<ModulePath>,
106 pub content: ImportContent,
107}
108
109#[cfg(feature = "imports")]
110#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
111#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
112#[derive(Clone, Debug, PartialEq, Eq, Hash, IsVariant)]
113pub enum PathOrigin {
114 Absolute,
116 Relative(usize),
118 Package(String),
120}
121
122#[cfg(feature = "imports")]
123#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
124#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
125#[derive(Clone, Debug, PartialEq, Eq, Hash)]
126pub struct ModulePath {
127 pub origin: PathOrigin,
128 pub components: Vec<String>,
129}
130
131#[cfg(feature = "imports")]
132#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
133#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
134#[derive(Clone, Debug, PartialEq)]
135pub struct Import {
136 pub path: Vec<String>,
137 pub content: ImportContent,
138}
139
140#[cfg(feature = "imports")]
141#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
142#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
143#[derive(Clone, Debug, PartialEq, IsVariant)]
144pub enum ImportContent {
145 Item(ImportItem),
146 Collection(Vec<Import>),
147}
148
149#[cfg(feature = "imports")]
150#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
151#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
152#[derive(Clone, Debug, PartialEq)]
153pub struct ImportItem {
154 pub ident: Ident,
155 pub rename: Option<Ident>,
156}
157
158#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
159#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
160#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
161pub enum GlobalDirective {
162 Diagnostic(DiagnosticDirective),
163 Enable(EnableDirective),
164 Requires(RequiresDirective),
165}
166
167#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
168#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
169#[derive(Clone, Debug, PartialEq)]
170pub struct DiagnosticDirective {
171 #[cfg(feature = "attributes")]
172 pub attributes: Attributes,
173 pub severity: DiagnosticSeverity,
174 pub rule_name: String,
175}
176
177#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
178#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
179#[derive(Clone, Debug, PartialEq)]
180pub struct EnableDirective {
181 #[cfg(feature = "attributes")]
182 pub attributes: Attributes,
183 pub extensions: Vec<String>,
184}
185
186#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
187#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
188#[derive(Clone, Debug, PartialEq)]
189pub struct RequiresDirective {
190 #[cfg(feature = "attributes")]
191 pub attributes: Attributes,
192 pub extensions: Vec<String>,
193}
194
195#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
196#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
197#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
198pub enum GlobalDeclaration {
199 Void,
200 Declaration(Declaration),
201 TypeAlias(TypeAlias),
202 Struct(Struct),
203 Function(Function),
204 ConstAssert(ConstAssert),
205 #[cfg(feature = "condcomp")]
206 Compound(CompoundGlobalDeclaration),
207}
208
209pub type GlobalDeclarationNode = Spanned<GlobalDeclaration>;
210
211#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
212#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
213#[derive(Clone, Debug, PartialEq)]
214pub struct Declaration {
215 pub attributes: Attributes,
216 pub kind: DeclarationKind,
217 pub ident: Ident,
218 pub ty: Option<TypeExpression>,
219 pub initializer: Option<ExpressionNode>,
220}
221
222#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
223#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
224#[derive(Clone, Copy, Debug, PartialEq, Eq, IsVariant)]
225pub enum DeclarationKind {
226 Const,
227 Override,
228 Let,
229 Var(Option<(AddressSpace, Option<AccessMode>)>), }
231
232#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
233#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
234#[derive(Clone, Debug, PartialEq)]
235pub struct TypeAlias {
236 #[cfg(feature = "attributes")]
237 pub attributes: Attributes,
238 pub ident: Ident,
239 pub ty: TypeExpression,
240}
241
242#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
243#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
244#[derive(Clone, Debug, PartialEq)]
245pub struct Struct {
246 #[cfg(feature = "attributes")]
247 pub attributes: Attributes,
248 pub ident: Ident,
249 pub members: Vec<StructMemberNode>,
250}
251
252#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
253#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
254#[derive(Clone, Debug, PartialEq)]
255pub struct StructMember {
256 pub attributes: Attributes,
257 pub ident: Ident,
258 pub ty: TypeExpression,
259}
260
261pub type StructMemberNode = Spanned<StructMember>;
262
263#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
264#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
265#[derive(Clone, Debug, PartialEq)]
266pub struct Function {
267 pub attributes: Attributes,
268 pub ident: Ident,
269 pub parameters: Vec<FormalParameter>,
270 pub return_attributes: Attributes,
271 pub return_type: Option<TypeExpression>,
272 pub body: CompoundStatement,
273}
274
275#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
276#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
277#[derive(Clone, Debug, PartialEq)]
278pub struct FormalParameter {
279 pub attributes: Attributes,
280 pub ident: Ident,
281 pub ty: TypeExpression,
282}
283
284#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
285#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
286#[derive(Clone, Debug, PartialEq)]
287pub struct ConstAssert {
288 #[cfg(feature = "attributes")]
289 pub attributes: Attributes,
290 pub expression: ExpressionNode,
291}
292
293#[cfg(feature = "condcomp")]
294#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
295#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
296#[derive(Clone, Debug, PartialEq)]
297pub struct CompoundGlobalDeclaration {
298 pub attributes: Attributes,
299 pub body: Vec<GlobalDeclarationNode>,
300}
301
302#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
303#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
304#[derive(Clone, Debug, PartialEq)]
305pub struct DiagnosticAttribute {
306 pub severity: DiagnosticSeverity,
307 pub rule: String,
308}
309
310#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
311#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
312#[derive(Clone, Debug, PartialEq)]
313pub struct InterpolateAttribute {
314 pub ty: InterpolationType,
315 pub sampling: Option<InterpolationSampling>,
316}
317
318#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
319#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
320#[derive(Clone, Debug, PartialEq)]
321pub struct WorkgroupSizeAttribute {
322 pub x: ExpressionNode,
323 pub y: Option<ExpressionNode>,
324 pub z: Option<ExpressionNode>,
325}
326
327#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
328#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
329#[derive(Clone, Debug, PartialEq)]
330pub struct CustomAttribute {
331 pub name: String,
332 pub arguments: Option<Vec<ExpressionNode>>,
333}
334
335#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
336#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
337#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
338pub enum Attribute {
339 Align(ExpressionNode),
340 Binding(ExpressionNode),
341 BlendSrc(ExpressionNode),
342 #[from]
343 Builtin(BuiltinValue),
344 Const,
345 #[from]
346 Diagnostic(DiagnosticAttribute),
347 Group(ExpressionNode),
348 Id(ExpressionNode),
349 #[from]
350 Interpolate(InterpolateAttribute),
351 Invariant,
352 Location(ExpressionNode),
353 MustUse,
354 Size(ExpressionNode),
355 #[from]
356 WorkgroupSize(WorkgroupSizeAttribute),
357 Vertex,
358 Fragment,
359 Compute,
360 #[cfg(feature = "naga-ext")]
361 Task,
362 #[cfg(feature = "naga-ext")]
363 Payload(ExpressionNode),
364 #[cfg(feature = "naga-ext")]
365 Mesh(ExpressionNode),
366 #[cfg(feature = "imports")]
367 Publish,
368 #[cfg(feature = "condcomp")]
369 If(ExpressionNode),
370 #[cfg(feature = "condcomp")]
371 Elif(ExpressionNode),
372 #[cfg(feature = "condcomp")]
373 Else,
374 #[cfg(feature = "generics")]
375 #[from]
376 Type(TypeConstraint),
377 #[cfg(feature = "naga-ext")]
378 EarlyDepthTest(Option<ConservativeDepth>),
379 #[from]
380 Custom(CustomAttribute),
381}
382
383impl Attribute {
384 pub fn is_entry_point(&self) -> bool {
385 match self {
386 Attribute::Vertex | Attribute::Fragment | Attribute::Compute => true,
387 #[cfg(feature = "naga-ext")]
388 Attribute::Task | Attribute::Mesh(_) => true,
389 _ => false,
390 }
391 }
392
393 #[cfg(feature = "condcomp")]
394 pub fn is_condcomp(&self) -> bool {
395 matches!(
396 self,
397 Attribute::If(_) | Attribute::Elif(_) | Attribute::Else
398 )
399 }
400}
401
402pub type AttributeNode = Spanned<Attribute>;
403
404#[cfg(feature = "generics")]
405#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
406#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
407#[derive(Clone, Debug, PartialEq, From)]
408pub struct TypeConstraint {
409 pub ident: Ident,
410 pub variants: Vec<TypeExpression>,
411}
412
413pub type Attributes = Vec<AttributeNode>;
414
415#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
416#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
417#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
418pub enum Expression {
419 Literal(LiteralExpression),
420 Parenthesized(ParenthesizedExpression),
421 NamedComponent(NamedComponentExpression),
422 Indexing(IndexingExpression),
423 Unary(UnaryExpression),
424 Binary(BinaryExpression),
425 FunctionCall(FunctionCallExpression),
426 TypeOrIdentifier(TypeExpression),
427}
428
429pub type ExpressionNode = Spanned<Expression>;
430
431#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
432#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
433#[derive(Clone, Copy, Debug, PartialEq, From, IsVariant, Unwrap)]
434pub enum LiteralExpression {
435 Bool(bool),
436 AbstractInt(i64),
437 AbstractFloat(f64),
438 I32(i32),
439 U32(u32),
440 F32(f32),
441 #[from(skip)]
442 F16(f32),
443 #[cfg(feature = "naga-ext")]
444 #[from(skip)]
445 I64(i64),
446 #[cfg(feature = "naga-ext")]
447 #[from(skip)]
448 U64(u64),
449 #[cfg(feature = "naga-ext")]
450 #[from(skip)]
451 F64(f64),
452}
453
454#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
455#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
456#[derive(Clone, Debug, PartialEq)]
457pub struct ParenthesizedExpression {
458 pub expression: ExpressionNode,
459}
460
461#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
462#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
463#[derive(Clone, Debug, PartialEq)]
464pub struct NamedComponentExpression {
465 pub base: ExpressionNode,
466 pub component: Ident,
467}
468
469#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
470#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
471#[derive(Clone, Debug, PartialEq)]
472pub struct IndexingExpression {
473 pub base: ExpressionNode,
474 pub index: ExpressionNode,
475}
476
477#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
478#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
479#[derive(Clone, Debug, PartialEq)]
480pub struct UnaryExpression {
481 pub operator: UnaryOperator,
482 pub operand: ExpressionNode,
483}
484
485#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
486#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
487#[derive(Clone, Debug, PartialEq)]
488pub struct BinaryExpression {
489 pub operator: BinaryOperator,
490 pub left: ExpressionNode,
491 pub right: ExpressionNode,
492}
493
494#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
495#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
496#[derive(Clone, Debug, PartialEq)]
497pub struct FunctionCall {
498 pub ty: TypeExpression,
499 pub arguments: Vec<ExpressionNode>,
500}
501
502pub type FunctionCallExpression = FunctionCall;
503
504#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
505#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
506#[derive(Clone, Debug, PartialEq)]
507pub struct TypeExpression {
508 #[cfg(feature = "imports")]
509 pub path: Option<ModulePath>,
510 pub ident: Ident,
511 pub template_args: TemplateArgs,
512}
513
514#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
515#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
516#[derive(Clone, Debug, PartialEq)]
517pub struct TemplateArg {
518 pub expression: ExpressionNode,
519}
520pub type TemplateArgs = Option<Vec<TemplateArg>>;
521
522#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
523#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
524#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
525pub enum Statement {
526 Void,
527 Compound(CompoundStatement),
528 Assignment(AssignmentStatement),
529 Increment(IncrementStatement),
530 Decrement(DecrementStatement),
531 If(IfStatement),
532 Switch(SwitchStatement),
533 Loop(LoopStatement),
534 For(ForStatement),
535 While(WhileStatement),
536 Break(BreakStatement),
537 Continue(ContinueStatement),
538 Return(ReturnStatement),
539 Discard(DiscardStatement),
540 FunctionCall(FunctionCallStatement),
541 ConstAssert(ConstAssertStatement),
542 Declaration(DeclarationStatement),
543}
544
545pub type StatementNode = Spanned<Statement>;
546
547#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
548#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
549#[derive(Clone, Debug, PartialEq, Default)]
550pub struct CompoundStatement {
551 pub attributes: Attributes,
552 pub statements: Vec<StatementNode>,
553}
554
555#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
556#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
557#[derive(Clone, Debug, PartialEq)]
558pub struct AssignmentStatement {
559 #[cfg(feature = "attributes")]
560 pub attributes: Attributes,
561 pub operator: AssignmentOperator,
562 pub lhs: ExpressionNode,
563 pub rhs: ExpressionNode,
564}
565
566#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
567#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
568#[derive(Clone, Debug, PartialEq)]
569pub struct IncrementStatement {
570 #[cfg(feature = "attributes")]
571 pub attributes: Attributes,
572 pub expression: ExpressionNode,
573}
574
575#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
576#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
577#[derive(Clone, Debug, PartialEq)]
578pub struct DecrementStatement {
579 #[cfg(feature = "attributes")]
580 pub attributes: Attributes,
581 pub expression: ExpressionNode,
582}
583
584#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
585#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
586#[derive(Clone, Debug, PartialEq)]
587pub struct IfStatement {
588 pub attributes: Attributes,
589 pub if_clause: IfClause,
590 pub else_if_clauses: Vec<ElseIfClause>,
591 pub else_clause: Option<ElseClause>,
592}
593
594#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
595#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
596#[derive(Clone, Debug, PartialEq)]
597pub struct IfClause {
598 pub expression: ExpressionNode,
599 pub body: CompoundStatement,
600}
601
602#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
603#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
604#[derive(Clone, Debug, PartialEq)]
605pub struct ElseIfClause {
606 #[cfg(feature = "attributes")]
607 pub attributes: Attributes,
608 pub expression: ExpressionNode,
609 pub body: CompoundStatement,
610}
611
612#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
613#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
614#[derive(Clone, Debug, PartialEq)]
615pub struct ElseClause {
616 #[cfg(feature = "attributes")]
617 pub attributes: Attributes,
618 pub body: CompoundStatement,
619}
620
621#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
622#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
623#[derive(Clone, Debug, PartialEq)]
624pub struct SwitchStatement {
625 pub attributes: Attributes,
626 pub expression: ExpressionNode,
627 pub body_attributes: Attributes,
628 pub clauses: Vec<SwitchClause>,
629}
630
631#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
632#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
633#[derive(Clone, Debug, PartialEq)]
634pub struct SwitchClause {
635 #[cfg(feature = "attributes")]
636 pub attributes: Attributes,
637 pub case_selectors: Vec<CaseSelector>,
638 pub body: CompoundStatement,
639}
640
641#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
642#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
643#[derive(Clone, Debug, PartialEq, From, IsVariant, Unwrap)]
644pub enum CaseSelector {
645 Default,
646 Expression(ExpressionNode),
647}
648
649#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
650#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
651#[derive(Clone, Debug, PartialEq)]
652pub struct LoopStatement {
653 pub attributes: Attributes,
654 pub body: CompoundStatement,
655 pub continuing: Option<ContinuingStatement>,
659}
660
661#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
662#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
663#[derive(Clone, Debug, PartialEq)]
664pub struct ContinuingStatement {
665 #[cfg(feature = "attributes")]
666 pub attributes: Attributes,
667 pub body: CompoundStatement,
668 pub break_if: Option<BreakIfStatement>,
672}
673
674#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
675#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
676#[derive(Clone, Debug, PartialEq)]
677pub struct BreakIfStatement {
678 #[cfg(feature = "attributes")]
679 pub attributes: Attributes,
680 pub expression: ExpressionNode,
681}
682
683#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
684#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
685#[derive(Clone, Debug, PartialEq)]
686pub struct ForStatement {
687 pub attributes: Attributes,
688 pub initializer: Option<StatementNode>,
689 pub condition: Option<ExpressionNode>,
690 pub update: Option<StatementNode>,
691 pub body: CompoundStatement,
692}
693
694#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
695#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
696#[derive(Clone, Debug, PartialEq)]
697pub struct WhileStatement {
698 pub attributes: Attributes,
699 pub condition: ExpressionNode,
700 pub body: CompoundStatement,
701}
702
703#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
704#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
705#[derive(Clone, Debug, PartialEq)]
706pub struct BreakStatement {
707 #[cfg(feature = "attributes")]
708 pub attributes: Attributes,
709}
710
711#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
712#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
713#[derive(Clone, Debug, PartialEq)]
714pub struct ContinueStatement {
715 #[cfg(feature = "attributes")]
716 pub attributes: Attributes,
717}
718
719#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
720#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
721#[derive(Clone, Debug, PartialEq)]
722pub struct ReturnStatement {
723 #[cfg(feature = "attributes")]
724 pub attributes: Attributes,
725 pub expression: Option<ExpressionNode>,
726}
727
728#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
729#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
730#[derive(Clone, Debug, PartialEq)]
731pub struct DiscardStatement {
732 #[cfg(feature = "attributes")]
733 pub attributes: Attributes,
734}
735
736#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
737#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
738#[derive(Clone, Debug, PartialEq)]
739pub struct FunctionCallStatement {
740 #[cfg(feature = "attributes")]
741 pub attributes: Attributes,
742 pub call: FunctionCall,
743}
744
745pub type ConstAssertStatement = ConstAssert;
746
747pub type DeclarationStatement = Declaration;