1use wgsl_types::inst::LiteralInstance;
2
3use super::syntax::*;
4use crate::span::Spanned;
5
6impl TranslationUnit {
7 pub fn new() -> Self {
9 Self::default()
10 }
11
12 pub fn remove_voids(&mut self) {
14 self.global_declarations
15 .retain_mut(|decl| match decl.node() {
16 GlobalDeclaration::Void => false,
17 _ => {
18 decl.remove_voids();
19 true
20 }
21 })
22 }
23
24 pub fn sort_declarations(&mut self) {
25 use std::cmp::Ordering::*;
26 type Decl = GlobalDeclaration;
27 self.global_declarations
28 .sort_unstable_by(|a, b| match (a.node(), b.node()) {
29 (Decl::Compound(_), Decl::Compound(_)) => Equal,
30 (Decl::Compound(_), _) => Less,
31 (_, Decl::Compound(_)) => Greater,
32
33 (Decl::Void, Decl::Void) => Equal,
34 (Decl::Void, Decl::Declaration(_)) => Less,
35 (Decl::Void, Decl::Struct(_)) => Less,
36 (Decl::Void, Decl::TypeAlias(_)) => Less,
37 (Decl::Void, Decl::ConstAssert(_)) => Less,
38 (Decl::Void, Decl::Function(_)) => Less,
39
40 (Decl::Declaration(_), Decl::Void) => Greater,
41 (Decl::Declaration(d1), Decl::Declaration(d2)) => {
42 match (d1.kind, d2.kind) {
45 (DeclarationKind::Const, DeclarationKind::Const)
46 | (DeclarationKind::Override, DeclarationKind::Override)
47 | (DeclarationKind::Let, DeclarationKind::Let)
48 | (DeclarationKind::Var(_), DeclarationKind::Var(_)) => {
49 d1.ident.name().cmp(&d2.ident.name())
50 }
51 (DeclarationKind::Const, DeclarationKind::Override) => Less,
52 (DeclarationKind::Const, DeclarationKind::Let) => Less,
53 (DeclarationKind::Const, DeclarationKind::Var(_)) => Less,
54 (DeclarationKind::Override, DeclarationKind::Const) => Greater,
55 (DeclarationKind::Override, DeclarationKind::Let) => Less,
56 (DeclarationKind::Override, DeclarationKind::Var(_)) => Less,
57 (DeclarationKind::Let, DeclarationKind::Const) => Greater,
58 (DeclarationKind::Let, DeclarationKind::Override) => Greater,
59 (DeclarationKind::Let, DeclarationKind::Var(_)) => Less,
60 (DeclarationKind::Var(_), DeclarationKind::Const) => Greater,
61 (DeclarationKind::Var(_), DeclarationKind::Override) => Greater,
62 (DeclarationKind::Var(_), DeclarationKind::Let) => Greater,
63 }
64 }
65 (Decl::Declaration(_), Decl::Struct(_)) => Less,
66 (Decl::Declaration(_), Decl::TypeAlias(_)) => Less,
67 (Decl::Declaration(_), Decl::ConstAssert(_)) => Less,
68 (Decl::Declaration(_), Decl::Function(_)) => Less,
69
70 (Decl::Struct(_), Decl::Void) => Greater,
71 (Decl::Struct(_), Decl::Declaration(_)) => Greater,
72 (Decl::Struct(d1), Decl::Struct(d2)) => d1.ident.name().cmp(&d2.ident.name()),
73 (Decl::Struct(_), Decl::TypeAlias(_)) => Less,
74 (Decl::Struct(_), Decl::ConstAssert(_)) => Less,
75 (Decl::Struct(_), Decl::Function(_)) => Less,
76
77 (Decl::TypeAlias(_), Decl::Void) => Greater,
78 (Decl::TypeAlias(_), Decl::Declaration(_)) => Greater,
79 (Decl::TypeAlias(_), Decl::Struct(_)) => Greater,
80 (Decl::TypeAlias(d1), Decl::TypeAlias(d2)) => d1.ident.name().cmp(&d2.ident.name()),
81 (Decl::TypeAlias(_), Decl::ConstAssert(_)) => Less,
82 (Decl::TypeAlias(_), Decl::Function(_)) => Less,
83
84 (Decl::ConstAssert(_), Decl::Void) => Greater,
85 (Decl::ConstAssert(_), Decl::Declaration(_)) => Greater,
86 (Decl::ConstAssert(_), Decl::Struct(_)) => Greater,
87 (Decl::ConstAssert(_), Decl::TypeAlias(_)) => Greater,
88 (Decl::ConstAssert(c1), Decl::ConstAssert(c2)) => {
89 c1.to_string().cmp(&c2.to_string())
91 }
92 (Decl::ConstAssert(_), Decl::Function(_)) => Less,
93
94 (Decl::Function(_), Decl::Void) => Greater,
95 (Decl::Function(_), Decl::Declaration(_)) => Greater,
96 (Decl::Function(_), Decl::Struct(_)) => Greater,
97 (Decl::Function(_), Decl::TypeAlias(_)) => Greater,
98 (Decl::Function(_), Decl::ConstAssert(_)) => Greater,
99 (Decl::Function(d1), Decl::Function(d2)) => d1.ident.name().cmp(&d2.ident.name()),
100 });
101 }
102}
103
104impl ModulePath {
105 pub fn new(origin: PathOrigin, components: Vec<String>) -> Self {
109 Self { origin, components }
110 }
111
112 pub fn new_root() -> Self {
118 Self::new(PathOrigin::Absolute, vec![])
119 }
120
121 pub fn from_path(path: impl AsRef<std::path::Path>) -> Self {
134 use std::path::Component;
135 let path = path.as_ref().with_extension("");
136 let mut parts = path.components().peekable();
137
138 let origin = match parts.next() {
139 Some(Component::Prefix(_)) => panic!("path starts with a Windows prefix"),
140 Some(Component::RootDir) => PathOrigin::Absolute,
141 Some(Component::CurDir) => PathOrigin::Relative(0),
142 Some(Component::ParentDir) => {
143 let mut n = 1;
144 while let Some(&Component::ParentDir) = parts.peek() {
145 n += 1;
146 parts.next().unwrap();
147 }
148 PathOrigin::Relative(n)
149 }
150 Some(Component::Normal(name)) => {
151 PathOrigin::Package(name.to_string_lossy().to_string())
152 }
153 None => panic!("path is empty"),
154 };
155
156 let mut components = Vec::new();
157 for part in parts {
158 match part {
159 Component::Prefix(_) | Component::RootDir => panic!("unexpected path component"),
160 Component::CurDir => {}
161 Component::ParentDir => {
162 components.pop().expect("path escapes its origin");
163 }
165 Component::Normal(name) => {
166 components.push(name.to_string_lossy().to_string());
167 }
168 }
169 }
170
171 Self { origin, components }
172 }
173
174 pub fn to_path_buf(&self) -> std::path::PathBuf {
180 use std::path::PathBuf;
181 let mut fs_path = match &self.origin {
182 PathOrigin::Absolute => PathBuf::from("/"),
183 PathOrigin::Relative(0) => PathBuf::from("."),
184 PathOrigin::Relative(n) => PathBuf::from_iter((0..*n).map(|_| "..")),
185 PathOrigin::Package(name) => PathBuf::from(name),
186 };
187 fs_path.extend(&self.components);
188 fs_path
189 }
190
191 pub fn push(&mut self, item: &str) {
195 self.components.push(item.to_string());
196 }
197
198 pub fn first(&self) -> Option<&str> {
200 self.components.first().map(String::as_str)
201 }
202
203 pub fn last(&self) -> Option<&str> {
205 self.components.last().map(String::as_str)
206 }
207
208 pub fn join(mut self, suffix: impl IntoIterator<Item = String>) -> Self {
210 self.components.extend(suffix);
211 self
212 }
213
214 pub fn join_path(&self, suffix: &Self) -> Self {
225 match suffix.origin {
226 PathOrigin::Absolute => {
227 match self.origin {
228 PathOrigin::Absolute | PathOrigin::Relative(_) => suffix.clone(),
229 PathOrigin::Package(_) => {
230 let origin = self.origin.clone();
232 let components = suffix.components.clone();
233 Self { origin, components }
234 }
235 }
236 }
237 PathOrigin::Relative(n) => {
238 let to_keep = self.components.len().saturating_sub(n);
239 let components = self
240 .components
241 .iter()
242 .take(to_keep)
243 .chain(&suffix.components)
244 .cloned()
245 .collect::<Vec<_>>();
246 let origin = match self.origin {
247 PathOrigin::Absolute | PathOrigin::Package(_) => self.origin.clone(),
248 PathOrigin::Relative(m) => {
249 PathOrigin::Relative(m + n.saturating_sub(self.components.len()))
250 }
251 };
252 Self { origin, components }
253 }
254 PathOrigin::Package(ref suffix_pkg) => {
255 match &self.origin {
256 PathOrigin::Absolute | PathOrigin::Relative(_) => suffix.clone(),
257 PathOrigin::Package(self_pkg) => {
258 if self_pkg.rsplit('/').next() == suffix_pkg.rsplit('/').next() {
259 let origin = self.origin.clone();
261 let components = suffix.components.clone();
262 Self { origin, components }
263 } else {
264 let origin = PathOrigin::Package(format!("{self_pkg}/{suffix_pkg}"));
267 let components = suffix.components.clone();
268 Self { origin, components }
269 }
270 }
271 }
272 }
273 }
274 }
275
276 pub fn starts_with(&self, prefix: &Self) -> bool {
278 self.origin == prefix.origin
279 && self.components.len() >= prefix.components.len()
280 && prefix
281 .components
282 .iter()
283 .zip(&self.components)
284 .all(|(a, b)| a == b)
285 }
286
287 pub fn is_root(&self) -> bool {
291 self.origin.is_absolute() && self.components.is_empty()
292 }
293}
294
295#[test]
296fn test_module_path_join() {
297 use std::str::FromStr;
298 let cases = [
299 ("package::m1", "package::foo", "package::foo"),
300 ("package::m1", "self::foo", "package::m1::foo"),
301 ("package::m1", "super::foo", "package::foo"),
302 ("pkg::m1::m2", "package::foo", "pkg::foo"),
303 ("pkg::m1::m2", "self::foo", "pkg::m1::m2::foo"),
304 ("pkg::m1::m2", "super::foo", "pkg::m1::foo"),
305 ("pkg::m1", "super::super::foo", "pkg::foo"),
306 ("lygia::m1", "lygia::math", "lygia::math"),
307 ("lygia::m1", "pkg/lygia", "lygia"),
308 ("pkg/lygia::m1", "lygia", "pkg/lygia"),
309 ("pkg/lygia::m1", "lygia::math", "pkg/lygia::math"),
310 ("pkg1/lygia::m1", "pkg2/lygia::math", "pkg1/lygia::math"),
311 ("super", "super::foo", "super::super::foo"),
312 ("super::m1::m2::m3", "super::super::m4", "super::m1::m4"),
313 ("super", "self::foo", "super::foo"),
314 ("self", "super::foo", "super::foo"),
315 ];
316
317 for (parent, child, expect) in cases {
318 let parent = ModulePath::from_str(parent).unwrap();
319 let child = ModulePath::from_str(child).unwrap();
320 let expect = ModulePath::from_str(expect).unwrap();
321 println!("testing ModulePath::join_path({parent}, {child}) -> {expect}");
322 assert_eq!(parent.join_path(&child), expect);
323 }
324}
325
326#[derive(Clone, Copy, PartialEq, Eq, Debug, thiserror::Error)]
327pub enum ModulePathParseError {
328 #[error("module name cannot be empty")]
329 Empty,
330 #[error("`package` must be a prefix of the module path")]
331 MisplacedPackage,
332 #[error("`self` must be a prefix of the module path")]
333 MisplacedSelf,
334 #[error("`super` must be a prefix of the module path")]
335 MisplacedSuper,
336}
337
338impl std::str::FromStr for ModulePath {
339 type Err = ModulePathParseError;
340
341 fn from_str(s: &str) -> Result<Self, Self::Err> {
346 let mut parts = s.split("::").peekable();
347
348 let origin = match parts.next() {
349 Some("package") => PathOrigin::Absolute,
350 Some("self") => PathOrigin::Relative(0),
351 Some("super") => {
352 let mut n = 1;
353 while let Some(&"super") = parts.peek() {
354 n += 1;
355 parts.next().unwrap();
356 }
357 PathOrigin::Relative(n)
358 }
359 Some("") | None => return Err(ModulePathParseError::Empty),
360 Some(name) => PathOrigin::Package(name.to_string()),
361 };
362
363 let components = parts
364 .map(|part| match part {
365 "package" => Err(ModulePathParseError::MisplacedPackage),
366 "self" => Err(ModulePathParseError::MisplacedSelf),
367 "super" => Err(ModulePathParseError::MisplacedSuper),
368 _ => Ok(part.to_string()),
369 })
370 .collect::<Result<Vec<_>, _>>()?;
371
372 Ok(Self { origin, components })
373 }
374}
375
376#[test]
377fn test_module_path_fromstr() {
378 use std::str::FromStr;
379
380 let ok_cases = [
381 ("self", ModulePath::new(PathOrigin::Relative(0), vec![])),
382 ("super", ModulePath::new(PathOrigin::Relative(1), vec![])),
383 ("package", ModulePath::new(PathOrigin::Absolute, vec![])),
384 (
385 "a",
386 ModulePath::new(PathOrigin::Package("a".to_string()), vec![]),
387 ),
388 (
389 "super::super::a",
390 ModulePath::new(PathOrigin::Relative(2), vec!["a".to_string()]),
391 ),
392 ];
393 let err_cases = [
394 ("", ModulePathParseError::Empty),
395 ("a::super", ModulePathParseError::MisplacedSuper),
396 ("super::self", ModulePathParseError::MisplacedSelf),
397 ("self::package", ModulePathParseError::MisplacedPackage),
398 ];
399
400 for (s, m) in ok_cases {
401 assert_eq!(ModulePath::from_str(s), Ok(m))
402 }
403 for (s, e) in err_cases {
404 assert_eq!(ModulePath::from_str(s), Err(e))
405 }
406}
407
408impl GlobalDeclaration {
409 pub fn remove_voids(&mut self) {
411 if let GlobalDeclaration::Function(decl) = self {
412 decl.body.remove_voids();
413 }
414 }
415
416 pub fn visibility(&self) -> Visibility {
418 match self {
419 GlobalDeclaration::Declaration(decl) => decl.visibility,
420 GlobalDeclaration::TypeAlias(decl) => decl.visibility,
421 GlobalDeclaration::Struct(decl) => decl.visibility,
422 GlobalDeclaration::Function(decl) => decl.visibility,
423 GlobalDeclaration::Void
424 | GlobalDeclaration::ConstAssert(_)
425 | GlobalDeclaration::Compound(_) => Visibility::Private,
426 }
427 }
428}
429
430impl TypeAlias {
431 pub fn new(ident: Ident, ty: TypeExpression) -> Self {
432 Self {
433 attributes: Default::default(),
434 visibility: Default::default(),
435 ident,
436 ty,
437 }
438 }
439}
440
441impl Struct {
442 pub fn new(ident: Ident) -> Self {
443 Self {
444 attributes: Default::default(),
445 visibility: Default::default(),
446 ident,
447 members: Default::default(),
448 }
449 }
450}
451
452impl StructMember {
453 pub fn new(ident: Ident, ty: TypeExpression) -> Self {
454 Self {
455 attributes: Default::default(),
456 ident,
457 ty,
458 }
459 }
460}
461
462impl Function {
463 pub fn new(ident: Ident) -> Self {
464 Self {
465 attributes: Default::default(),
466 visibility: Default::default(),
467 ident,
468 parameters: Default::default(),
469 return_attributes: Default::default(),
470 return_type: Default::default(),
471 body: Default::default(),
472 }
473 }
474}
475
476impl FormalParameter {
477 pub fn new(ident: Ident, ty: TypeExpression) -> Self {
478 Self {
479 attributes: Default::default(),
480 ident,
481 ty,
482 }
483 }
484}
485
486impl ConstAssert {
487 pub fn new(expression: Expression) -> Self {
488 Self {
489 attributes: Default::default(),
490 expression: expression.into(),
491 }
492 }
493}
494
495impl TypeExpression {
496 pub fn new(ident: Ident) -> Self {
498 Self {
499 path: None,
500 ident,
501 template_args: None,
502 }
503 }
504}
505
506impl CompoundStatement {
507 pub fn remove_voids(&mut self) {
509 self.statements.retain_mut(|stmt| match stmt.node_mut() {
510 Statement::Void => false,
511 _ => {
512 stmt.remove_voids();
513 true
514 }
515 })
516 }
517}
518
519impl Statement {
520 pub fn remove_voids(&mut self) {
522 match self {
523 Statement::Compound(stmt) => {
524 stmt.remove_voids();
525 }
526 Statement::If(stmt) => {
527 stmt.if_clause.body.remove_voids();
528 for clause in &mut stmt.else_if_clauses {
529 clause.body.remove_voids();
530 }
531 if let Some(clause) = &mut stmt.else_clause {
532 clause.body.remove_voids();
533 }
534 }
535 Statement::Switch(stmt) => stmt
536 .clauses
537 .iter_mut()
538 .for_each(|clause| clause.body.remove_voids()),
539 Statement::Loop(stmt) => stmt.body.remove_voids(),
540 Statement::For(stmt) => stmt.body.remove_voids(),
541 Statement::While(stmt) => stmt.body.remove_voids(),
542 _ => (),
543 }
544 }
545}
546
547impl From<LiteralExpression> for LiteralInstance {
548 fn from(lit: LiteralExpression) -> Self {
549 match lit {
550 LiteralExpression::Bool(l) => LiteralInstance::Bool(l),
551 LiteralExpression::AbstractInt(l) => LiteralInstance::AbstractInt(l),
552 LiteralExpression::AbstractFloat(l) => LiteralInstance::AbstractFloat(l),
553 LiteralExpression::I32(l) => LiteralInstance::I32(l),
554 LiteralExpression::U32(l) => LiteralInstance::U32(l),
555 LiteralExpression::F32(l) => LiteralInstance::F32(l),
556 LiteralExpression::F16(l) => LiteralInstance::F16(wgsl_types::f16::from_f32(l)),
557 #[cfg(feature = "naga-ext")]
558 LiteralExpression::I64(l) => LiteralInstance::I64(l),
559 #[cfg(feature = "naga-ext")]
560 LiteralExpression::U64(l) => LiteralInstance::U64(l),
561 #[cfg(feature = "naga-ext")]
562 LiteralExpression::F64(l) => LiteralInstance::F64(l),
563 }
564 }
565}
566
567impl From<Ident> for TypeExpression {
568 fn from(ident: Ident) -> Self {
569 Self::new(ident)
570 }
571}
572
573impl From<ExpressionNode> for ReturnStatement {
574 fn from(expression: ExpressionNode) -> Self {
575 Self {
576 attributes: Default::default(),
577 expression: Some(expression),
578 }
579 }
580}
581impl From<Expression> for ReturnStatement {
582 fn from(expression: Expression) -> Self {
583 Self::from(ExpressionNode::from(expression))
584 }
585}
586
587impl From<FunctionCall> for FunctionCallStatement {
588 fn from(call: FunctionCall) -> Self {
589 Self {
590 attributes: Default::default(),
591 call,
592 }
593 }
594}
595
596macro_rules! impl_transitive_from {
600 ($from:ident => $middle:ident => $into:ident) => {
601 impl From<$from> for $into {
602 fn from(value: $from) -> Self {
603 $into::from($middle::from(value))
604 }
605 }
606 };
607}
608
609impl_transitive_from!(bool => LiteralExpression => Expression);
610impl_transitive_from!(i64 => LiteralExpression => Expression);
611impl_transitive_from!(f64 => LiteralExpression => Expression);
612impl_transitive_from!(i32 => LiteralExpression => Expression);
613impl_transitive_from!(u32 => LiteralExpression => Expression);
614impl_transitive_from!(f32 => LiteralExpression => Expression);
615impl_transitive_from!(Ident => TypeExpression => Expression);
616
617pub trait SyntaxNode {
622 fn span(&self) -> Option<Span> {
624 None
625 }
626
627 fn ident(&self) -> Option<Ident> {
629 None
630 }
631
632 fn attributes(&self) -> &[AttributeNode] {
634 &[]
635 }
636 fn attributes_mut(&mut self) -> &mut [AttributeNode] {
638 &mut []
639 }
640 fn contains_attribute(&self, attribute: &Attribute) -> bool {
642 self.attributes().iter().any(|v| v.node() == attribute)
643 }
644 fn retain_attributes_mut<F>(&mut self, _predicate: F)
646 where
647 F: FnMut(&mut Attribute) -> bool,
648 {
649 }
650}
651
652impl<T: SyntaxNode> SyntaxNode for Spanned<T> {
653 fn span(&self) -> Option<Span> {
654 Some(self.span())
655 }
656
657 fn ident(&self) -> Option<Ident> {
658 self.node().ident()
659 }
660
661 fn attributes(&self) -> &[AttributeNode] {
662 self.node().attributes()
663 }
664
665 fn attributes_mut(&mut self) -> &mut [AttributeNode] {
666 self.node_mut().attributes_mut()
667 }
668
669 fn retain_attributes_mut<F>(&mut self, mut f: F)
670 where
671 F: FnMut(&mut Attribute) -> bool,
672 {
673 self.node_mut().retain_attributes_mut(|v| f(v))
674 }
675}
676
677macro_rules! impl_attrs_struct {
678 () => {
679 fn attributes(&self) -> &[AttributeNode] {
680 &self.attributes
681 }
682 fn attributes_mut(&mut self) -> &mut [AttributeNode] {
683 &mut self.attributes
684 }
685 fn retain_attributes_mut<F>(&mut self, mut f: F)
686 where
687 F: FnMut(&mut Attribute) -> bool,
688 {
689 self.attributes.retain_mut(|v| f(v))
690 }
691 };
692}
693
694#[allow(unused)]
695macro_rules! impl_attrs_enum {
696 ($($variant: path),* $(,)?) => {
697 fn attributes(&self) -> &[AttributeNode] {
698 match self {
699 $(
700 $variant(x) => &x.attributes,
701 )*
702 #[allow(unreachable_patterns)]
703 _ => &[]
704 }
705 }
706 fn attributes_mut(&mut self) -> &mut [AttributeNode] {
707 match self {
708 $(
709 $variant(x) => &mut x.attributes,
710 )*
711 #[allow(unreachable_patterns)]
712 _ => &mut []
713 }
714 }
715 fn retain_attributes_mut<F>(&mut self, mut f: F)
716 where
717 F: FnMut(&mut Attribute) -> bool,
718 {
719 match self {
720 $(
721 $variant(x) => x.attributes.retain_mut(|v| f(v)),
722 )*
723 #[allow(unreachable_patterns)]
724 _ => {}
725 }
726 }
727 };
728}
729
730impl SyntaxNode for ImportStatement {
731 impl_attrs_struct! {}
732}
733
734impl SyntaxNode for GlobalDirective {
735 impl_attrs_enum! {
736 GlobalDirective::Diagnostic,
737 GlobalDirective::Enable,
738 GlobalDirective::Requires
739 }
740}
741
742impl SyntaxNode for DiagnosticDirective {
743 impl_attrs_struct! {}
744}
745
746impl SyntaxNode for EnableDirective {
747 impl_attrs_struct! {}
748}
749
750impl SyntaxNode for RequiresDirective {
751 impl_attrs_struct! {}
752}
753
754impl SyntaxNode for GlobalDeclaration {
755 fn ident(&self) -> Option<Ident> {
756 match self {
757 GlobalDeclaration::Void => None,
758 GlobalDeclaration::Declaration(decl) => Some(decl.ident.clone()),
759 GlobalDeclaration::TypeAlias(decl) => Some(decl.ident.clone()),
760 GlobalDeclaration::Struct(decl) => Some(decl.ident.clone()),
761 GlobalDeclaration::Function(decl) => Some(decl.ident.clone()),
762 GlobalDeclaration::ConstAssert(_) => None,
763 GlobalDeclaration::Compound(_) => None,
764 }
765 }
766
767 impl_attrs_enum! {
768 GlobalDeclaration::Declaration,
769 GlobalDeclaration::TypeAlias,
770 GlobalDeclaration::Struct,
771 GlobalDeclaration::Function,
772 GlobalDeclaration::ConstAssert,
773 GlobalDeclaration::Compound,
774 }
775}
776
777impl SyntaxNode for Declaration {
778 fn ident(&self) -> Option<Ident> {
779 Some(self.ident.clone())
780 }
781
782 impl_attrs_struct! {}
783}
784
785impl SyntaxNode for TypeAlias {
786 fn ident(&self) -> Option<Ident> {
787 Some(self.ident.clone())
788 }
789
790 impl_attrs_struct! {}
791}
792
793impl SyntaxNode for Struct {
794 fn ident(&self) -> Option<Ident> {
795 Some(self.ident.clone())
796 }
797
798 impl_attrs_struct! {}
799}
800
801impl SyntaxNode for StructMember {
802 fn ident(&self) -> Option<Ident> {
803 Some(self.ident.clone())
804 }
805
806 impl_attrs_struct! {}
807}
808
809impl SyntaxNode for Function {
810 fn ident(&self) -> Option<Ident> {
811 Some(self.ident.clone())
812 }
813
814 impl_attrs_struct! {}
815}
816
817impl SyntaxNode for FormalParameter {
818 fn ident(&self) -> Option<Ident> {
819 Some(self.ident.clone())
820 }
821
822 impl_attrs_struct! {}
823}
824
825impl SyntaxNode for ConstAssert {
826 impl_attrs_struct! {}
827}
828
829impl SyntaxNode for Expression {}
830impl SyntaxNode for LiteralExpression {}
831impl SyntaxNode for ParenthesizedExpression {}
832impl SyntaxNode for NamedComponentExpression {}
833impl SyntaxNode for IndexingExpression {}
834impl SyntaxNode for UnaryExpression {}
835impl SyntaxNode for BinaryExpression {}
836impl SyntaxNode for FunctionCall {}
837impl SyntaxNode for TypeExpression {}
838
839impl SyntaxNode for Statement {
840 impl_attrs_enum! {
841 Statement::Compound,
842 Statement::Assignment,
843 Statement::Increment,
844 Statement::Decrement,
845 Statement::If,
846 Statement::Switch,
847 Statement::Loop,
848 Statement::For,
849 Statement::While,
850 Statement::Break,
851 Statement::Continue,
852 Statement::Return,
853 Statement::Discard,
854 Statement::FunctionCall,
855 Statement::ConstAssert,
856 Statement::Declaration,
857 }
858}
859
860impl SyntaxNode for CompoundStatement {
861 impl_attrs_struct! {}
862}
863
864impl SyntaxNode for AssignmentStatement {
865 impl_attrs_struct! {}
866}
867
868impl SyntaxNode for IncrementStatement {
869 impl_attrs_struct! {}
870}
871
872impl SyntaxNode for DecrementStatement {
873 impl_attrs_struct! {}
874}
875
876impl SyntaxNode for IfStatement {
877 impl_attrs_struct! {}
878}
879
880impl SyntaxNode for IfClause {}
881
882impl SyntaxNode for ElseIfClause {
883 impl_attrs_struct! {}
884}
885
886impl SyntaxNode for ElseClause {
887 impl_attrs_struct! {}
888}
889
890impl SyntaxNode for SwitchStatement {
891 impl_attrs_struct! {}
892}
893
894impl SyntaxNode for SwitchClause {
895 impl_attrs_struct! {}
896}
897
898impl SyntaxNode for LoopStatement {
899 impl_attrs_struct! {}
900}
901
902impl SyntaxNode for ContinuingStatement {
903 impl_attrs_struct! {}
904}
905
906impl SyntaxNode for BreakIfStatement {
907 impl_attrs_struct! {}
908}
909
910impl SyntaxNode for ForStatement {
911 impl_attrs_struct! {}
912}
913
914impl SyntaxNode for WhileStatement {
915 impl_attrs_struct! {}
916}
917
918impl SyntaxNode for BreakStatement {
919 impl_attrs_struct! {}
920}
921
922impl SyntaxNode for ContinueStatement {
923 impl_attrs_struct! {}
924}
925
926impl SyntaxNode for ReturnStatement {
927 impl_attrs_struct! {}
928}
929
930impl SyntaxNode for DiscardStatement {
931 impl_attrs_struct! {}
932}
933
934impl SyntaxNode for FunctionCallStatement {
935 impl_attrs_struct! {}
936}