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