aboutsummaryrefslogtreecommitdiff
path: root/xtask/src
diff options
context:
space:
mode:
Diffstat (limited to 'xtask/src')
-rw-r--r--xtask/src/ast_src.rs1984
-rw-r--r--xtask/src/codegen/gen_syntax.rs224
-rw-r--r--xtask/src/codegen/rust.ungram529
3 files changed, 754 insertions, 1983 deletions
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index a6a4d7c35..83449437b 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -223,12 +223,14 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
223 ], 223 ],
224}; 224};
225 225
226#[derive(Default, Debug)]
226pub(crate) struct AstSrc { 227pub(crate) struct AstSrc {
227 pub(crate) tokens: Vec<String>, 228 pub(crate) tokens: Vec<String>,
228 pub(crate) nodes: Vec<AstNodeSrc>, 229 pub(crate) nodes: Vec<AstNodeSrc>,
229 pub(crate) enums: Vec<AstEnumSrc>, 230 pub(crate) enums: Vec<AstEnumSrc>,
230} 231}
231 232
233#[derive(Debug)]
232pub(crate) struct AstNodeSrc { 234pub(crate) struct AstNodeSrc {
233 pub(crate) doc: Vec<String>, 235 pub(crate) doc: Vec<String>,
234 pub(crate) name: String, 236 pub(crate) name: String,
@@ -236,1999 +238,23 @@ pub(crate) struct AstNodeSrc {
236 pub(crate) fields: Vec<Field>, 238 pub(crate) fields: Vec<Field>,
237} 239}
238 240
241#[derive(Debug, Eq, PartialEq)]
239pub(crate) enum Field { 242pub(crate) enum Field {
240 Token(String), 243 Token(String),
241 Node { name: String, src: FieldSrc }, 244 Node { name: String, src: FieldSrc },
242} 245}
243 246
247#[derive(Debug, Eq, PartialEq)]
244pub(crate) enum FieldSrc { 248pub(crate) enum FieldSrc {
245 Shorthand, 249 Shorthand,
246 Optional(String), 250 Optional(String),
247 Many(String), 251 Many(String),
248} 252}
249 253
254#[derive(Debug)]
250pub(crate) struct AstEnumSrc { 255pub(crate) struct AstEnumSrc {
251 pub(crate) doc: Vec<String>, 256 pub(crate) doc: Vec<String>,
252 pub(crate) name: String, 257 pub(crate) name: String,
253 pub(crate) traits: Vec<String>, 258 pub(crate) traits: Vec<String>,
254 pub(crate) variants: Vec<String>, 259 pub(crate) variants: Vec<String>,
255} 260}
256
257macro_rules! ast_nodes {
258 ($(
259 $(#[doc = $doc:expr])+
260 struct $name:ident$(: $($trait:ident),*)? {
261 $($field_name:ident $(![$token:tt])? $(: $ty:tt)?),*$(,)?
262 }
263 )*) => {
264 vec![$(
265 AstNodeSrc {
266 doc: vec![$($doc.to_string()),*],
267 name: stringify!($name).to_string(),
268 traits: vec![$($(stringify!($trait).to_string()),*)?],
269 fields: vec![
270 $(field!($(T![$token])? $field_name $($ty)?)),*
271 ],
272
273 }
274 ),*]
275 };
276}
277
278macro_rules! field {
279 (T![$token:tt] T) => {
280 Field::Token(stringify!($token).to_string())
281 };
282 ($field_name:ident) => {
283 Field::Node { name: stringify!($field_name).to_string(), src: FieldSrc::Shorthand }
284 };
285 ($field_name:ident [$ty:ident]) => {
286 Field::Node {
287 name: stringify!($field_name).to_string(),
288 src: FieldSrc::Many(stringify!($ty).to_string()),
289 }
290 };
291 ($field_name:ident $ty:ident) => {
292 Field::Node {
293 name: stringify!($field_name).to_string(),
294 src: FieldSrc::Optional(stringify!($ty).to_string()),
295 }
296 };
297}
298
299macro_rules! ast_enums {
300 ($(
301 $(#[doc = $doc:expr])+
302 enum $name:ident $(: $($trait:ident),*)? {
303 $($variant:ident),*$(,)?
304 }
305 )*) => {
306 vec![$(
307 AstEnumSrc {
308 doc: vec![$($doc.to_string()),*],
309 name: stringify!($name).to_string(),
310 traits: vec![$($(stringify!($trait).to_string()),*)?],
311 variants: vec![$(stringify!($variant).to_string()),*],
312 }
313 ),*]
314 };
315}
316
317pub(crate) fn rust_ast() -> AstSrc {
318 AstSrc {
319 tokens: vec!["Whitespace".into(), "Comment".into(), "String".into(), "RawString".into()],
320 nodes: ast_nodes! {
321 /// The entire Rust source file. Includes all top-level inner attributes and module items.
322 ///
323 /// [Reference](https://doc.rust-lang.org/reference/crates-and-source-files.html)
324 struct SourceFile: ModuleItemOwner, AttrsOwner, DocCommentsOwner {
325 }
326
327 /// Function definition either with body or not.
328 /// Includes all of its attributes and doc comments.
329 ///
330 /// ```
331 /// ❰
332 /// /// Docs
333 /// #[attr]
334 /// pub extern "C" fn foo<T>(#[attr] Patern {p}: Pattern) -> u32
335 /// where
336 /// T: Debug
337 /// {
338 /// 42
339 /// }
340 /// ❱
341 ///
342 /// extern "C" {
343 /// ❰ fn fn_decl(also_variadic_ffi: u32, ...) -> u32; ❱
344 /// }
345 /// ```
346 ///
347 /// - [Reference](https://doc.rust-lang.org/reference/items/functions.html)
348 /// - [Nomicon](https://doc.rust-lang.org/nomicon/ffi.html#variadic-functions)
349 struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner {
350 Abi,
351 T![const],
352 T![default],
353 T![async],
354 T![unsafe],
355 T![fn],
356 ParamList,
357 RetType,
358 body: BlockExpr,
359 T![;]
360 }
361
362 /// Return type annotation.
363 ///
364 /// ```
365 /// fn foo(a: u32) ❰ -> Option<u32> ❱ { Some(a) }
366 /// ```
367 ///
368 /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
369 struct RetType { T![->], TypeRef }
370
371 /// Struct definition.
372 /// Includes all of its attributes and doc comments.
373 ///
374 /// ```
375 /// ❰
376 /// /// Docs
377 /// #[attr]
378 /// struct Foo<T> where T: Debug {
379 /// /// Docs
380 /// #[attr]
381 /// pub a: u32,
382 /// b: T,
383 /// }
384 /// ❱
385 ///
386 /// ❰ struct Foo; ❱
387 /// ❰ struct Foo<T>(#[attr] T) where T: Debug; ❱
388 /// ```
389 ///
390 /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
391 struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
392 T![struct],
393 FieldDefList,
394 T![;]
395 }
396
397 /// Union definition.
398 /// Includes all of its attributes and doc comments.
399 ///
400 /// ```
401 /// ❰
402 /// /// Docs
403 /// #[attr]
404 /// pub union Foo<T> where T: Debug {
405 /// /// Docs
406 /// #[attr]
407 /// a: T,
408 /// b: u32,
409 /// }
410 /// ❱
411 /// ```
412 ///
413 /// [Reference](https://doc.rust-lang.org/reference/items/unions.html)
414 struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
415 T![union],
416 RecordFieldDefList,
417 }
418
419 /// Record field definition list including enclosing curly braces.
420 ///
421 /// ```
422 /// struct Foo // same for union
423 /// ❰
424 /// {
425 /// a: u32,
426 /// b: bool,
427 /// }
428 /// ❱
429 /// ```
430 ///
431 /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
432 struct RecordFieldDefList { T!['{'], fields: [RecordFieldDef], T!['}'] }
433
434 /// Record field definition including its attributes and doc comments.
435 ///
436 /// ` ``
437 /// same for union
438 /// struct Foo {
439 /// ❰
440 /// /// Docs
441 /// #[attr]
442 /// pub a: u32
443 /// ❱
444 ///
445 /// ❰ b: bool ❱
446 /// }
447 /// ```
448 ///
449 /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
450 struct RecordFieldDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { }
451
452 /// Tuple field definition list including enclosing parens.
453 ///
454 /// ```
455 /// struct Foo ❰ (u32, String, Vec<u32>) ❱;
456 /// ```
457 ///
458 /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
459 struct TupleFieldDefList { T!['('], fields: [TupleFieldDef], T![')'] }
460
461 /// Tuple field definition including its attributes.
462 ///
463 /// ```
464 /// struct Foo(❰ #[attr] u32 ❱);
465 /// ```
466 ///
467 /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
468 struct TupleFieldDef: VisibilityOwner, AttrsOwner {
469 TypeRef,
470 }
471
472 /// Enum definition.
473 /// Includes all of its attributes and doc comments.
474 ///
475 /// ```
476 /// ❰
477 /// /// Docs
478 /// #[attr]
479 /// pub enum Foo<T> where T: Debug {
480 /// /// Docs
481 /// #[attr]
482 /// Bar,
483 /// Baz(#[attr] u32),
484 /// Bruh {
485 /// a: u32,
486 /// /// Docs
487 /// #[attr]
488 /// b: T,
489 /// }
490 /// }
491 /// ❱
492 /// ```
493 ///
494 /// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
495 struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
496 T![enum],
497 variant_list: EnumVariantList,
498 }
499
500 /// Enum variant definition list including enclosing curly braces.
501 ///
502 /// ```
503 /// enum Foo
504 /// ❰
505 /// {
506 /// Bar,
507 /// Baz(u32),
508 /// Bruh {
509 /// a: u32
510 /// }
511 /// }
512 /// ❱
513 /// ```
514 ///
515 /// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
516 struct EnumVariantList {
517 T!['{'],
518 variants: [EnumVariant],
519 T!['}']
520 }
521
522 /// Enum variant definition including its attributes and discriminant value definition.
523 ///
524 /// ```
525 /// enum Foo {
526 /// ❰
527 /// /// Docs
528 /// #[attr]
529 /// Bar
530 /// ❱
531 ///
532 /// // same for tuple and record variants
533 /// }
534 /// ```
535 ///
536 /// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
537 struct EnumVariant: VisibilityOwner, NameOwner, DocCommentsOwner, AttrsOwner {
538 FieldDefList,
539 T![=],
540 Expr
541 }
542
543 /// Trait definition.
544 /// Includes all of its attributes and doc comments.
545 ///
546 /// ```
547 /// ❰
548 /// /// Docs
549 /// #[attr]
550 /// pub unsafe trait Foo<T>: Debug where T: Debug {
551 /// // ...
552 /// }
553 /// ❱
554 /// ```
555 ///
556 /// [Reference](https://doc.rust-lang.org/reference/items/traits.html)
557 struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner {
558 T![unsafe],
559 T![auto],
560 T![trait],
561 ItemList,
562 }
563
564 /// Module definition either with body or not.
565 /// Includes all of its inner and outer attributes, module items, doc comments.
566 ///
567 /// ```
568 /// ❰
569 /// /// Docs
570 /// #[attr]
571 /// pub mod foo;
572 /// ❱
573 ///
574 /// ❰
575 /// /// Docs
576 /// #[attr]
577 /// pub mod bar {
578 /// //! Inner docs
579 /// #![inner_attr]
580 /// }
581 /// ❱
582 /// ```
583 ///
584 /// [Reference](https://doc.rust-lang.org/reference/items/modules.html)
585 struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner {
586 T![mod],
587 ItemList,
588 T![;]
589 }
590
591 /// Item defintion list.
592 /// This is used for both top-level items and impl block items.
593 ///
594 /// ```
595 /// ❰
596 /// fn foo {}
597 /// struct Bar;
598 /// enum Baz;
599 /// trait Bruh;
600 /// const BRUUH: u32 = 42;
601 /// ❱
602 ///
603 /// impl Foo
604 /// ❰
605 /// {
606 /// fn bar() {}
607 /// const BAZ: u32 = 42;
608 /// }
609 /// ❱
610 /// ```
611 ///
612 /// [Reference](https://doc.rust-lang.org/reference/items.html)
613 struct ItemList: ModuleItemOwner {
614 T!['{'],
615 assoc_items: [AssocItem],
616 T!['}']
617 }
618
619 /// Constant variable definition.
620 /// Includes all of its attributes and doc comments.
621 ///
622 /// ```
623 /// ❰
624 /// /// Docs
625 /// #[attr]
626 /// pub const FOO: u32 = 42;
627 /// ❱
628 /// ```
629 ///
630 /// [Reference](https://doc.rust-lang.org/reference/items/constant-items.html)
631 struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
632 T![default],
633 T![const],
634 T![=],
635 body: Expr,
636 T![;]
637 }
638
639
640 /// Static variable definition.
641 /// Includes all of its attributes and doc comments.
642 ///
643 /// ```
644 /// ❰
645 /// /// Docs
646 /// #[attr]
647 /// pub static mut FOO: u32 = 42;
648 /// ❱
649 /// ```
650 ///
651 /// [Reference](https://doc.rust-lang.org/reference/items/static-items.html)
652 struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
653 T![static],
654 T![mut],
655 T![=],
656 body: Expr,
657 T![;]
658 }
659
660 /// Type alias definition.
661 /// Includes associated type clauses with type bounds.
662 ///
663 /// ```
664 /// ❰
665 /// /// Docs
666 /// #[attr]
667 /// pub type Foo<T> where T: Debug = T;
668 /// ❱
669 ///
670 /// trait Bar {
671 /// ❰ type Baz: Debug; ❱
672 /// ❰ type Bruh = String; ❱
673 /// ❰ type Bruuh: Debug = u32; ❱
674 /// }
675 /// ```
676 ///
677 /// [Reference](https://doc.rust-lang.org/reference/items/type-aliases.html)
678 struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner {
679 T![default],
680 T![type],
681 T![=],
682 TypeRef,
683 T![;]
684 }
685
686 /// Inherent and trait impl definition.
687 /// Includes all of its inner and outer attributes.
688 ///
689 /// ```
690 /// ❰
691 /// #[attr]
692 /// unsafe impl<T> const !Foo for Bar where T: Debug {
693 /// #![inner_attr]
694 /// // ...
695 /// }
696 /// ❱
697 /// ```
698 ///
699 /// [Reference](https://doc.rust-lang.org/reference/items/implementations.html)
700 struct ImplDef: TypeParamsOwner, AttrsOwner, DocCommentsOwner {
701 T![default],
702 T![const],
703 T![unsafe],
704 T![impl],
705 T![!],
706 T![for],
707 ItemList,
708 }
709
710
711 /// Parenthesized type reference.
712 /// Note: parens are only used for grouping, this is not a tuple type.
713 ///
714 /// ```
715 /// // This is effectively just `u32`.
716 /// // Single-item tuple must be defined with a trailing comma: `(u32,)`
717 /// type Foo = ❰ (u32) ❱;
718 ///
719 /// let bar: &'static ❰ (dyn Debug) ❱ = "bruh";
720 /// ```
721 struct ParenType { T!['('], TypeRef, T![')'] }
722
723 /// Unnamed tuple type.
724 ///
725 /// ```
726 /// let foo: ❰ (u32, bool) ❱ = (42, true);
727 /// ```
728 ///
729 /// [Reference](https://doc.rust-lang.org/reference/types/tuple.html)
730 struct TupleType { T!['('], fields: [TypeRef], T![')'] }
731
732 /// The never type (i.e. the exclamation point).
733 ///
734 /// ```
735 /// type T = ❰ ! ❱;
736 ///
737 /// fn no_return() -> ❰ ! ❱ {
738 /// loop {}
739 /// }
740 /// ```
741 ///
742 /// [Reference](https://doc.rust-lang.org/reference/types/never.html)
743 struct NeverType { T![!] }
744
745 /// Path to a type.
746 /// Includes single identifier type names and elaborate paths with
747 /// generic parameters.
748 ///
749 /// ```
750 /// type Foo = ❰ String ❱;
751 /// type Bar = ❰ std::vec::Vec<T> ❱;
752 /// type Baz = ❰ ::bruh::<Bruuh as Iterator>::Item ❱;
753 /// ```
754 ///
755 /// [Reference](https://doc.rust-lang.org/reference/paths.html)
756 struct PathType { Path }
757
758 /// Raw pointer type.
759 ///
760 /// ```
761 /// type Foo = ❰ *const u32 ❱;
762 /// type Bar = ❰ *mut u32 ❱;
763 /// ```
764 ///
765 /// [Reference](https://doc.rust-lang.org/reference/types/pointer.html#raw-pointers-const-and-mut)
766 struct PointerType { T![*], T![const], T![mut], TypeRef }
767
768 /// Array type.
769 ///
770 /// ```
771 /// type Foo = ❰ [u32; 24 - 3] ❱;
772 /// ```
773 ///
774 /// [Reference](https://doc.rust-lang.org/reference/types/array.html)
775 struct ArrayType { T!['['], TypeRef, T![;], Expr, T![']'] }
776
777 /// Slice type.
778 ///
779 /// ```
780 /// type Foo = ❰ [u8] ❱;
781 /// ```
782 ///
783 /// [Reference](https://doc.rust-lang.org/reference/types/slice.html)
784 struct SliceType { T!['['], TypeRef, T![']'] }
785
786 /// Reference type.
787 ///
788 /// ```
789 /// type Foo = ❰ &'static str ❱;
790 /// ```
791 ///
792 /// [Reference](https://doc.rust-lang.org/reference/types/pointer.html)
793 struct ReferenceType { T![&], T![lifetime], T![mut], TypeRef }
794
795 /// Placeholder type (i.e. the underscore).
796 ///
797 /// ```
798 /// let foo: ❰ _ ❱ = 42_u32;
799 /// ```
800 ///
801 /// [Reference](https://doc.rust-lang.org/reference/types/inferred.html)
802 struct PlaceholderType { T![_] }
803
804 /// Function pointer type (not to be confused with `Fn*` family of traits).
805 ///
806 /// ```
807 /// type Foo = ❰ async fn(#[attr] u32, named: bool) -> u32 ❱;
808 ///
809 /// type Bar = ❰ extern "C" fn(variadic: u32, #[attr] ...) ❱;
810 /// ```
811 ///
812 /// [Reference](https://doc.rust-lang.org/reference/types/function-pointer.html)
813 struct FnPointerType { Abi, T![unsafe], T![fn], ParamList, RetType }
814
815 /// Higher order type.
816 ///
817 /// ```
818 /// type Foo = ❰ for<'a> fn(&'a str) ❱;
819 /// ```
820 ///
821 /// [Reference](https://doc.rust-lang.org/nomicon/hrtb.html)
822 struct ForType { T![for], TypeParamList, TypeRef }
823
824 /// Opaque `impl Trait` type.
825 ///
826 /// ```
827 /// fn foo(bar: ❰ impl Debug + Eq ❱) {}
828 /// ```
829 ///
830 /// [Reference](https://doc.rust-lang.org/reference/types/impl-trait.html)
831 struct ImplTraitType: TypeBoundsOwner { T![impl] }
832
833 /// Trait object type.
834 ///
835 /// ```
836 /// type Foo = ❰ dyn Debug ❱;
837 /// ```
838 ///
839 /// [Reference](https://doc.rust-lang.org/reference/types/trait-object.html)
840 struct DynTraitType: TypeBoundsOwner { T![dyn] }
841
842 /// Tuple literal.
843 ///
844 /// ```
845 /// ❰ (42, true) ❱;
846 /// ```
847 ///
848 /// [Reference](https://doc.rust-lang.org/reference/expressions/tuple-expr.html)
849 struct TupleExpr: AttrsOwner { T!['('], exprs: [Expr], T![')'] }
850
851 /// Array literal.
852 ///
853 /// ```
854 /// ❰ [#![inner_attr] true, false, true] ❱;
855 ///
856 /// ❰ ["baz"; 24] ❱;
857 /// ```
858 ///
859 /// [Reference](https://doc.rust-lang.org/reference/expressions/array-expr.html)
860 struct ArrayExpr: AttrsOwner { T!['['], exprs: [Expr], T![;], T![']'] }
861
862 /// Parenthesized expression.
863 /// Note: parens are only used for grouping, this is not a tuple literal.
864 ///
865 /// ```
866 /// ❰ (#![inner_attr] 2 + 2) ❱ * 2;
867 /// ```
868 ///
869 /// [Reference](https://doc.rust-lang.org/reference/expressions/grouped-expr.html)
870 struct ParenExpr: AttrsOwner { T!['('], Expr, T![')'] }
871
872 /// Path to a symbol in expression context.
873 /// Includes single identifier variable names and elaborate paths with
874 /// generic parameters.
875 ///
876 /// ```
877 /// ❰ Some::<i32> ❱;
878 /// ❰ foo ❱ + 42;
879 /// ❰ Vec::<i32>::push ❱;
880 /// ❰ <[i32]>::reverse ❱;
881 /// ❰ <String as std::borrow::Borrow<str>>::borrow ❱;
882 /// ```
883 ///
884 /// [Reference](https://doc.rust-lang.org/reference/expressions/path-expr.html)
885 struct PathExpr { Path }
886
887 /// Anonymous callable object literal a.k.a. closure, lambda or functor.
888 ///
889 /// ```
890 /// ❰ || 42 ❱;
891 /// ❰ |a: u32| val + 1 ❱;
892 /// ❰ async |#[attr] Pattern(_): Pattern| { bar } ❱;
893 /// ❰ move || baz ❱;
894 /// ❰ || -> u32 { closure_with_ret_type_annotation_requires_block_expr } ❱
895 /// ```
896 ///
897 /// [Reference](https://doc.rust-lang.org/reference/expressions/closure-expr.html)
898 struct LambdaExpr: AttrsOwner {
899 T![static], // Note(@matklad): I belive this is (used to be?) syntax for generators
900 T![async],
901 T![move],
902 ParamList,
903 RetType,
904 body: Expr,
905 }
906
907 /// If expression. Includes both regular `if` and `if let` forms.
908 /// Beware that `else if` is a special case syntax sugar, because in general
909 /// there has to be block expression after `else`.
910 ///
911 /// ```
912 /// ❰ if bool_cond { 42 } ❱
913 /// ❰ if bool_cond { 42 } else { 24 } ❱
914 /// ❰ if bool_cond { 42 } else if bool_cond2 { 42 } ❱
915 ///
916 /// ❰
917 /// if let Pattern(foo) = bar {
918 /// foo
919 /// } else {
920 /// panic!();
921 /// }
922 /// ❱
923 /// ```
924 ///
925 /// [Reference](https://doc.rust-lang.org/reference/expressions/if-expr.html)
926 struct IfExpr: AttrsOwner { T![if], Condition }
927
928 /// Unconditional loop expression.
929 ///
930 /// ```
931 /// ❰
932 /// loop {
933 /// // yeah, it's that simple...
934 /// }
935 /// ❱
936 /// ```
937 ///
938 /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html)
939 struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] }
940
941 /// Block expression with an optional prefix (label, try ketword,
942 /// unsafe keyword, async keyword...).
943 ///
944 /// ```
945 /// ❰
946 /// 'label: try {
947 /// None?
948 /// }
949 /// ❱
950 /// ```
951 ///
952 /// - [try block](https://doc.rust-lang.org/unstable-book/language-features/try-blocks.html)
953 /// - [unsafe block](https://doc.rust-lang.org/reference/expressions/block-expr.html#unsafe-blocks)
954 /// - [async block](https://doc.rust-lang.org/reference/expressions/block-expr.html#async-blocks)
955 struct EffectExpr: AttrsOwner { Label, T![try], T![unsafe], T![async], BlockExpr }
956
957
958 /// For loop expression.
959 /// Note: record struct literals are not valid as iterable expression
960 /// due to ambiguity.
961 ///
962 /// ```
963 /// ❰
964 /// for i in (0..4) {
965 /// dbg!(i);
966 /// }
967 /// ❱
968 /// ```
969 ///
970 /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops)
971 struct ForExpr: AttrsOwner, LoopBodyOwner {
972 T![for],
973 Pat,
974 T![in],
975 iterable: Expr,
976 }
977
978 /// While loop expression. Includes both regular `while` and `while let` forms.
979 ///
980 /// ```
981 /// ❰
982 /// while bool_cond {
983 /// 42;
984 /// }
985 /// ❱
986 /// ❰
987 /// while let Pattern(foo) = bar {
988 /// bar += 1;
989 /// }
990 /// ❱
991 /// ```
992 ///
993 /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-loops)
994 struct WhileExpr: AttrsOwner, LoopBodyOwner { T![while], Condition }
995
996 /// Continue expression.
997 ///
998 /// ```
999 /// while bool_cond {
1000 /// ❰ continue ❱;
1001 /// }
1002 ///
1003 /// 'outer: loop {
1004 /// loop {
1005 /// ❰ continue 'outer ❱;
1006 /// }
1007 /// }
1008 ///
1009 /// ```
1010 ///
1011 /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#continue-expressions)
1012 struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] }
1013
1014 /// Break expression.
1015 ///
1016 /// ```
1017 /// while bool_cond {
1018 /// ❰ break ❱;
1019 /// }
1020 /// 'outer: loop {
1021 /// for foo in bar {
1022 /// ❰ break 'outer ❱;
1023 /// }
1024 /// }
1025 /// 'outer: loop {
1026 /// loop {
1027 /// ❰ break 'outer 42 ❱;
1028 /// }
1029 /// }
1030 /// ```
1031 ///
1032 /// [Refernce](https://doc.rust-lang.org/reference/expressions/loop-expr.html#break-expressions)
1033 struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr }
1034
1035 /// Label.
1036 ///
1037 /// ```
1038 /// ❰ 'outer: ❱ loop {}
1039 ///
1040 /// let foo = ❰ 'bar: ❱ loop {}
1041 ///
1042 /// ❰ 'baz: ❱ {
1043 /// break 'baz;
1044 /// }
1045 /// ```
1046 ///
1047 /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html?highlight=label#loop-labels)
1048 /// [Labels for blocks RFC](https://github.com/rust-lang/rfcs/blob/master/text/2046-label-break-value.md)
1049 struct Label { T![lifetime] }
1050
1051 /// Block expression. Includes unsafe blocks and block labels.
1052 ///
1053 /// ```
1054 /// let foo = ❰
1055 /// {
1056 /// #![inner_attr]
1057 /// ❰ { } ❱
1058 ///
1059 /// ❰ 'label: { break 'label } ❱
1060 /// }
1061 /// ❱;
1062 /// ```
1063 ///
1064 /// [Reference](https://doc.rust-lang.org/reference/expressions/block-expr.html)
1065 /// [Labels for blocks RFC](https://github.com/rust-lang/rfcs/blob/master/text/2046-label-break-value.md)
1066 struct BlockExpr: AttrsOwner, ModuleItemOwner {
1067 Label, T!['{'], statements: [Stmt], Expr, T!['}'],
1068 }
1069
1070 /// Return expression.
1071 ///
1072 /// ```
1073 /// || ❰ return 42 ❱;
1074 ///
1075 /// fn bar() {
1076 /// ❰ return ❱;
1077 /// }
1078 /// ```
1079 ///
1080 /// [Reference](https://doc.rust-lang.org/reference/expressions/return-expr.html)
1081 struct ReturnExpr: AttrsOwner { Expr }
1082
1083 /// Call expression (not to be confused with method call expression, it is
1084 /// a separate ast node).
1085 ///
1086 /// ```
1087 /// ❰ foo() ❱;
1088 /// ❰ &str::len("bar") ❱;
1089 /// ❰ <&str as PartialEq<&str>>::eq(&"", &"") ❱;
1090 /// ```
1091 ///
1092 /// [Reference](https://doc.rust-lang.org/reference/expressions/call-expr.html)
1093 struct CallExpr: ArgListOwner { Expr }
1094
1095 /// Method call expression.
1096 ///
1097 /// ```
1098 /// ❰ receiver_expr.method() ❱;
1099 /// ❰ receiver_expr.method::<T>(42, true) ❱;
1100 ///
1101 /// ❰ ❰ ❰ foo.bar() ❱ .baz() ❱ .bruh() ❱;
1102 /// ```
1103 ///
1104 /// [Reference](https://doc.rust-lang.org/reference/expressions/method-call-expr.html)
1105 struct MethodCallExpr: AttrsOwner, ArgListOwner {
1106 Expr, T![.], NameRef, TypeArgList,
1107 }
1108
1109 /// Index expression a.k.a. subscript operator call.
1110 ///
1111 /// ```
1112 /// ❰ foo[42] ❱;
1113 /// ```
1114 ///
1115 /// [Reference](https://doc.rust-lang.org/reference/expressions/array-expr.html)
1116 struct IndexExpr: AttrsOwner { T!['['], T![']'] }
1117
1118 /// Field access expression.
1119 ///
1120 /// ```
1121 /// ❰ expr.bar ❱;
1122 ///
1123 /// ❰ ❰ ❰ foo.bar ❱ .baz ❱ .bruh ❱;
1124 /// ```
1125 ///
1126 /// [Reference](https://doc.rust-lang.org/reference/expressions/field-expr.html)
1127 struct FieldExpr: AttrsOwner { Expr, T![.], NameRef }
1128
1129 /// Await operator call expression.
1130 ///
1131 /// ```
1132 /// ❰ expr.await ❱;
1133 /// ```
1134 ///
1135 /// [Reference](https://doc.rust-lang.org/reference/expressions/await-expr.html)
1136 struct AwaitExpr: AttrsOwner { Expr, T![.], T![await] }
1137
1138 /// The question mark operator call.
1139 ///
1140 /// ```
1141 /// ❰ expr? ❱;
1142 /// ```
1143 ///
1144 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator)
1145 struct TryExpr: AttrsOwner { Expr, T![?] }
1146
1147 /// Type cast expression.
1148 ///
1149 /// ```
1150 /// ❰ expr as T ❱;
1151 /// ```
1152 ///
1153 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions)
1154 struct CastExpr: AttrsOwner { Expr, T![as], TypeRef }
1155
1156
1157 /// Borrow operator call.
1158 ///
1159 /// ```
1160 /// ❰ &foo ❱;
1161 /// ❰ &mut bar ❱;
1162 /// ❰ &raw const bar ❱;
1163 /// ❰ &raw mut bar ❱;
1164 /// ```
1165 ///
1166 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#borrow-operators)
1167 struct RefExpr: AttrsOwner { T![&], T![raw], T![mut], T![const], Expr }
1168
1169 /// Prefix operator call. This is either `!` or `*` or `-`.
1170 ///
1171 /// ```
1172 /// ❰ !foo ❱;
1173 /// ❰ *bar ❱;
1174 /// ❰ -42 ❱;
1175 /// ```
1176 ///
1177 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html)
1178 struct PrefixExpr: AttrsOwner { /*PrefixOp,*/ Expr }
1179
1180 /// Box operator call.
1181 ///
1182 /// ```
1183 /// ❰ box 42 ❱;
1184 /// ```
1185 ///
1186 /// [RFC](https://github.com/rust-lang/rfcs/blob/0806be4f282144cfcd55b1d20284b43f87cbe1c6/text/0809-box-and-in-for-stdlib.md)
1187 struct BoxExpr: AttrsOwner { T![box], Expr }
1188
1189 /// Range operator call.
1190 ///
1191 /// ```
1192 /// ❰ 0..42 ❱;
1193 /// ❰ ..42 ❱;
1194 /// ❰ 0.. ❱;
1195 /// ❰ .. ❱;
1196 /// ❰ 0..=42 ❱;
1197 /// ❰ ..=42 ❱;
1198 /// ```
1199 ///
1200 /// [Reference](https://doc.rust-lang.org/reference/expressions/range-expr.html)
1201 struct RangeExpr: AttrsOwner { /*RangeOp*/ }
1202
1203
1204 /// Binary operator call.
1205 /// Includes all arithmetic, logic, bitwise and assignment operators.
1206 ///
1207 /// ```
1208 /// ❰ 2 + ❰ 2 * 2 ❱ ❱;
1209 /// ❰ ❰ true && false ❱ || true ❱;
1210 /// ```
1211 ///
1212 /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators)
1213 struct BinExpr: AttrsOwner { /*BinOp*/ }
1214
1215
1216 /// [Raw] string, [raw] byte string, char, byte, integer, float or bool literal.
1217 ///
1218 /// ```
1219 /// ❰ "str" ❱;
1220 /// ❰ br##"raw byte str"## ❱;
1221 /// ❰ 'c' ❱;
1222 /// ❰ b'c' ❱;
1223 /// ❰ 42 ❱;
1224 /// ❰ 1e9 ❱;
1225 /// ❰ true ❱;
1226 /// ```
1227 ///
1228 /// [Reference](https://doc.rust-lang.org/reference/expressions/literal-expr.html)
1229 struct Literal { /*LiteralToken*/ }
1230
1231 /// Match expression.
1232 ///
1233 /// ```
1234 /// ❰
1235 /// match expr {
1236 /// Pat1 => {}
1237 /// Pat2(_) => 42,
1238 /// }
1239 /// ❱
1240 /// ```
1241 ///
1242 /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
1243 struct MatchExpr: AttrsOwner { T![match], Expr, MatchArmList }
1244
1245 /// Match arm list part of match expression. Includes its inner attributes.
1246 ///
1247 /// ```
1248 /// match expr
1249 /// ❰
1250 /// {
1251 /// #![inner_attr]
1252 /// Pat1 => {}
1253 /// Pat2(_) => 42,
1254 /// }
1255 /// ❱
1256 /// ```
1257 ///
1258 /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
1259 struct MatchArmList: AttrsOwner { T!['{'], arms: [MatchArm], T!['}'] }
1260
1261
1262 /// Match arm.
1263 /// Note: record struct literals are not valid as target match expression
1264 /// due to ambiguity.
1265 /// ```
1266 /// match expr {
1267 /// ❰ #[attr] Pattern(it) if bool_cond => it ❱,
1268 /// }
1269 /// ```
1270 ///
1271 /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
1272 struct MatchArm: AttrsOwner {
1273 pat: Pat,
1274 guard: MatchGuard,
1275 T![=>],
1276 Expr,
1277 }
1278
1279 /// Match guard.
1280 ///
1281 /// ```
1282 /// match expr {
1283 /// Pattern(it) ❰ if bool_cond ❱ => it,
1284 /// }
1285 /// ```
1286 ///
1287 /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html#match-guards)
1288 struct MatchGuard { T![if], Expr }
1289
1290 /// Record literal expression. The same syntax is used for structs,
1291 /// unions and record enum variants.
1292 ///
1293 /// ```
1294 /// ❰
1295 /// foo::Bar {
1296 /// #![inner_attr]
1297 /// baz: 42,
1298 /// bruh: true,
1299 /// ..spread
1300 /// }
1301 /// ❱
1302 /// ```
1303 ///
1304 /// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
1305 struct RecordLit { Path, RecordFieldList}
1306
1307 /// Record field list including enclosing curly braces.
1308 ///
1309 /// foo::Bar ❰
1310 /// {
1311 /// baz: 42,
1312 /// ..spread
1313 /// }
1314 /// ❱
1315 ///
1316 /// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
1317 struct RecordFieldList {
1318 T!['{'],
1319 fields: [RecordField],
1320 T![..],
1321 spread: Expr,
1322 T!['}']
1323 }
1324
1325 /// Record field.
1326 ///
1327 /// ```
1328 /// foo::Bar {
1329 /// ❰ #[attr] baz: 42 ❱
1330 /// }
1331 /// ```
1332 ///
1333 /// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
1334 struct RecordField: AttrsOwner { NameRef, T![:], Expr }
1335
1336 /// Disjunction of patterns.
1337 ///
1338 /// ```
1339 /// let ❰ Foo(it) | Bar(it) | Baz(it) ❱ = bruh;
1340 /// ```
1341 ///
1342 /// [Reference](https://doc.rust-lang.org/reference/patterns.html)
1343 struct OrPat { pats: [Pat] }
1344
1345 /// Parenthesized pattern.
1346 /// Note: parens are only used for grouping, this is not a tuple pattern.
1347 ///
1348 /// ```
1349 /// if let ❰ &(0..=42) ❱ = foo {}
1350 /// ```
1351 ///
1352 /// https://doc.rust-lang.org/reference/patterns.html#grouped-patterns
1353 struct ParenPat { T!['('], Pat, T![')'] }
1354
1355 /// Reference pattern.
1356 /// Note: this has nothing to do with `ref` keyword, the latter is used in bind patterns.
1357 ///
1358 /// ```
1359 /// let ❰ &mut foo ❱ = bar;
1360 ///
1361 /// let ❰ & ❰ &mut ❰ &_ ❱ ❱ ❱ = baz;
1362 /// ```
1363 ///
1364 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#reference-patterns)
1365 struct RefPat { T![&], T![mut], Pat }
1366
1367 /// Box pattern.
1368 ///
1369 /// ```
1370 /// let ❰ box foo ❱ = box 42;
1371 /// ```
1372 ///
1373 /// [Unstable book](https://doc.rust-lang.org/unstable-book/language-features/box-patterns.html)
1374 struct BoxPat { T![box], Pat }
1375
1376 /// Bind pattern.
1377 ///
1378 /// ```
1379 /// match foo {
1380 /// Some(❰ ref mut bar ❱) => {}
1381 /// ❰ baz @ None ❱ => {}
1382 /// }
1383 /// ```
1384 ///
1385 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#identifier-patterns)
1386 struct BindPat: AttrsOwner, NameOwner { T![ref], T![mut], T![@], Pat }
1387
1388 /// Placeholder pattern a.k.a. the wildcard pattern or the underscore.
1389 ///
1390 /// ```
1391 /// let ❰ _ ❱ = foo;
1392 /// ```
1393 ///
1394 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#wildcard-pattern)
1395 struct PlaceholderPat { T![_] }
1396
1397 /// Rest-of-the record/tuple pattern.
1398 /// Note: this is not the unbonded range pattern (even more: it doesn't exist).
1399 ///
1400 /// ```
1401 /// let Foo { bar, ❰ .. ❱ } = baz;
1402 /// let (❰ .. ❱, bruh) = (42, 24, 42);
1403 /// let Bruuh(❰ .. ❱) = bruuuh;
1404 /// ```
1405 ///
1406 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
1407 struct DotDotPat { T![..] }
1408
1409 /// Path pattern.
1410 /// Doesn't include the underscore pattern (it is a special case, namely `PlaceholderPat`).
1411 ///
1412 /// ```
1413 /// let ❰ foo::bar::Baz ❱ { .. } = bruh;
1414 /// if let ❰ CONST ❱ = 42 {}
1415 /// ```
1416 ///
1417 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#path-patterns)
1418 struct PathPat { Path }
1419
1420 /// Slice pattern.
1421 ///
1422 /// ```
1423 /// let ❰ [foo, bar, baz] ❱ = [1, 2, 3];
1424 /// ```
1425 ///
1426 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#slice-patterns)
1427 struct SlicePat { T!['['], args: [Pat], T![']'] }
1428
1429 /// Range pattern.
1430 ///
1431 /// ```
1432 /// match foo {
1433 /// ❰ 0..42 ❱ => {}
1434 /// ❰ 0..=42 ❱ => {}
1435 /// }
1436 /// ```
1437 ///
1438 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#range-patterns)
1439 struct RangePat { } // FIXME(@matklad): here should be T![..], T![..=] I think, if we don't already have an accessor in expresions_ext
1440
1441 /// Literal pattern.
1442 /// Includes only bool, number, char, and string literals.
1443 ///
1444 /// ```
1445 /// match foo {
1446 /// Number(❰ 42 ❱) => {}
1447 /// String(❰ "42" ❱) => {}
1448 /// Bool(❰ true ❱) => {}
1449 /// }
1450 /// ```
1451 ///
1452 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#literal-patterns)
1453 struct LiteralPat { Literal }
1454
1455 /// Macro invocation in pattern position.
1456 ///
1457 /// ```
1458 /// let ❰ foo!(my custom syntax) ❱ = baz;
1459 ///
1460 /// ```
1461 /// [Reference](https://doc.rust-lang.org/reference/macros.html#macro-invocation)
1462 struct MacroPat { MacroCall }
1463
1464 /// Record literal pattern.
1465 ///
1466 /// ```
1467 /// let ❰ foo::Bar { baz, .. } ❱ = bruh;
1468 /// ```
1469 ///
1470 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
1471 struct RecordPat { RecordFieldPatList, Path }
1472
1473 /// Record literal's field patterns list including enclosing curly braces.
1474 ///
1475 /// ```
1476 /// let foo::Bar ❰ { baz, bind @ bruh, .. } ❱ = bruuh;
1477 /// ``
1478 ///
1479 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
1480 struct RecordFieldPatList {
1481 T!['{'],
1482 record_field_pats: [RecordFieldPat],
1483 bind_pats: [BindPat],
1484 T![..],
1485 T!['}']
1486 }
1487
1488 /// Record literal's field pattern.
1489 /// Note: record literal can also match tuple structs.
1490 ///
1491 /// ```
1492 /// let Foo { ❰ bar: _ ❱ } = baz;
1493 /// let TupleStruct { ❰ 0: _ ❱ } = bruh;
1494 /// ```
1495 ///
1496 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
1497 struct RecordFieldPat: AttrsOwner { NameRef, T![:], Pat }
1498
1499 /// Tuple struct literal pattern.
1500 ///
1501 /// ```
1502 /// let ❰ foo::Bar(baz, bruh) ❱ = bruuh;
1503 /// ```
1504 ///
1505 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#tuple-struct-patterns)
1506 struct TupleStructPat { Path, T!['('], args: [Pat], T![')'] }
1507
1508 /// Tuple pattern.
1509 /// Note: this doesn't include tuple structs (see `TupleStructPat`)
1510 ///
1511 /// ```
1512 /// let ❰ (foo, bar, .., baz) ❱ = bruh;
1513 /// ```
1514 ///
1515 /// [Reference](https://doc.rust-lang.org/reference/patterns.html#tuple-patterns)
1516 struct TuplePat { T!['('], args: [Pat], T![')'] }
1517
1518 /// Visibility.
1519 ///
1520 /// ```
1521 /// ❰ pub mod ❱ foo;
1522 /// ❰ pub(crate) ❱ struct Bar;
1523 /// ❰ pub(self) ❱ enum Baz {}
1524 /// ❰ pub(super) ❱ fn bruh() {}
1525 /// ❰ pub(in bruuh::bruuuh) ❱ type T = u64;
1526 /// ```
1527 ///
1528 /// [Reference](https://doc.rust-lang.org/reference/visibility-and-privacy.html)
1529 struct Visibility { T![pub], T![super], T![self], T![crate] }
1530
1531 /// Single identifier.
1532 /// Note(@matklad): `Name` is for things that install a new name into the scope,
1533 /// `NameRef` is a usage of a name. Most of the time, this definition/reference
1534 /// distinction can be determined purely syntactically, ie in
1535 /// ```
1536 /// fn foo() { foo() }
1537 /// ```
1538 /// the first foo is `Name`, the second one is `NameRef`.
1539 /// The notable exception are patterns, where in
1540 /// ``
1541 /// let x = 92
1542 /// ```
1543 /// `x` can be semantically either a name or a name ref, depeding on
1544 /// wether there's an `x` constant in scope.
1545 /// We use `Name` for patterns, and disambiguate semantically (see `NameClass` in ide_db).
1546 ///
1547 /// ```
1548 /// let ❰ foo ❱ = bar;
1549 /// struct ❰ Baz ❱;
1550 /// fn ❰ bruh ❱() {}
1551 /// ```
1552 ///
1553 /// [Reference](https://doc.rust-lang.org/reference/identifiers.html)
1554 struct Name { T![ident] }
1555
1556 /// Reference to a name.
1557 /// See the explanation on the difference between `Name` and `NameRef`
1558 /// in `Name` ast node docs.
1559 ///
1560 /// ```
1561 /// let foo = ❰ bar ❱(❰ Baz(❰ bruh ❱) ❱;
1562 /// ```
1563 ///
1564 /// [Reference](https://doc.rust-lang.org/reference/identifiers.html)
1565 struct NameRef { }
1566
1567 /// Macro call.
1568 /// Includes all of its attributes and doc comments.
1569 ///
1570 /// ```
1571 /// ❰
1572 /// /// Docs
1573 /// #[attr]
1574 /// macro_rules! foo { // macro rules is also a macro call
1575 /// ($bar: tt) => {}
1576 /// }
1577 /// ❱
1578 ///
1579 /// // semicolon is a part of `MacroCall` when it is used in item positions
1580 /// ❰ foo!(); ❱
1581 ///
1582 /// fn main() {
1583 /// ❰ foo!() ❱; // macro call in expression positions doesn't include the semi
1584 /// }
1585 /// ```
1586 ///
1587 /// [Reference](https://doc.rust-lang.org/reference/macros.html)
1588 struct MacroCall: NameOwner, AttrsOwner, DocCommentsOwner {
1589 Path, T![!], TokenTree, T![;]
1590 }
1591
1592 /// Attribute.
1593 ///
1594 /// ```
1595 /// ❰ #![inner_attr] ❱
1596 ///
1597 /// ❰ #[attr] ❱
1598 /// ❰ #[foo = "bar"] ❱
1599 /// ❰ #[baz(bruh::bruuh = "42")] ❱
1600 /// struct Foo;
1601 /// ```
1602 ///
1603 /// [Reference](https://doc.rust-lang.org/reference/attributes.html)
1604 struct Attr { T![#], T![!], T!['['], Path, T![=], input: AttrInput, T![']'] }
1605
1606 /// Stores a list of lexer tokens and other `TokenTree`s.
1607 /// It appears in attributes, macro_rules and macro call (foo!)
1608 ///
1609 /// ```
1610 /// macro_call! ❰ { my syntax here } ❱;
1611 /// ```
1612 ///
1613 /// [Reference](https://doc.rust-lang.org/reference/macros.html)
1614 struct TokenTree {}
1615
1616 /// Generic lifetime, type and constants parameters list **declaration**.
1617 ///
1618 /// ```
1619 /// fn foo❰ <'a, 'b, T, U, const BAR: u64> ❱() {}
1620 ///
1621 /// struct Baz❰ <T> ❱(T);
1622 ///
1623 /// impl❰ <T> ❱ Bruh<T> {}
1624 ///
1625 /// type Bruuh = for❰ <'a> ❱ fn(&'a str) -> &'a str;
1626 /// ```
1627 ///
1628 /// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
1629 struct TypeParamList {
1630 T![<],
1631 type_params: [TypeParam],
1632 lifetime_params: [LifetimeParam],
1633 const_params: [ConstParam],
1634 T![>]
1635 }
1636
1637 /// Single type parameter **declaration**.
1638 ///
1639 /// ```
1640 /// fn foo<❰ K ❱, ❰ I ❱, ❰ E: Debug ❱, ❰ V = DefaultType ❱>() {}
1641 /// ```
1642 ///
1643 /// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
1644 struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner {
1645 T![=],
1646 default_type: TypeRef,
1647 }
1648
1649 /// Const generic parameter **declaration**.
1650 /// ```
1651 /// fn foo<T, U, ❰ const BAR: usize ❱, ❰ const BAZ: bool ❱>() {}
1652 /// ```
1653 ///
1654 /// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/2000-const-generics.md#declaring-a-const-parameter)
1655 struct ConstParam: NameOwner, AttrsOwner, TypeAscriptionOwner {
1656 T![=],
1657 default_val: Expr,
1658 }
1659
1660 /// Lifetime parameter **declaration**.
1661 ///
1662 /// ```
1663 /// fn foo<❰ 'a ❱, ❰ 'b ❱, V, G, D>(bar: &'a str, baz: &'b mut str) {}
1664 /// ```
1665 ///
1666 /// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
1667 struct LifetimeParam: AttrsOwner { T![lifetime] }
1668
1669 /// Type bound declaration clause.
1670 ///
1671 /// ```
1672 /// fn foo<T: ❰ ?Sized ❱ + ❰ Debug ❱>() {}
1673 ///
1674 /// trait Bar<T>
1675 /// where
1676 /// T: ❰ Send ❱ + ❰ Sync ❱
1677 /// {
1678 /// type Baz: ❰ !Sync ❱ + ❰ Debug ❱ + ❰ ?const Add ❱;
1679 /// }
1680 /// ```
1681 ///
1682 /// [Reference](https://doc.rust-lang.org/reference/trait-bounds.html)
1683 struct TypeBound { T![lifetime], /* Question, */ T![const], /* Question, */ TypeRef }
1684
1685 /// Type bounds list.
1686 ///
1687 /// ```
1688 ///
1689 /// fn foo<T: ❰ ?Sized + Debug ❱>() {}
1690 ///
1691 /// trait Bar<T>
1692 /// where
1693 /// T: ❰ Send + Sync ❱
1694 /// {
1695 /// type Baz: ❰ !Sync + Debug ❱;
1696 /// }
1697 /// ```
1698 ///
1699 /// [Reference](https://doc.rust-lang.org/reference/trait-bounds.html)
1700 struct TypeBoundList { bounds: [TypeBound] }
1701
1702 /// Single where predicate.
1703 ///
1704 /// ```
1705 /// trait Foo<'a, 'b, T>
1706 /// where
1707 /// ❰ 'a: 'b ❱,
1708 /// ❰ T: IntoIterator ❱,
1709 /// ❰ for<'c> <T as IntoIterator>::Item: Bar<'c> ❱
1710 /// {}
1711 /// ```
1712 ///
1713 /// [Reference](https://doc.rust-lang.org/reference/items/generics.html#where-clauses)
1714 struct WherePred: TypeBoundsOwner { T![for], TypeParamList, T![lifetime], TypeRef }
1715
1716 /// Where clause.
1717 ///
1718 /// ```
1719 /// trait Foo<'a, T> ❰ where 'a: 'static, T: Debug ❱ {}
1720 ///
1721 /// ```
1722 ///
1723 /// [Reference](https://doc.rust-lang.org/reference/items/generics.html#where-clauses)
1724 struct WhereClause { T![where], predicates: [WherePred] }
1725
1726 /// Abi declaration.
1727 /// Note: the abi string is optional.
1728 ///
1729 /// ```
1730 /// ❰ extern "C" ❱ {
1731 /// fn foo() {}
1732 /// }
1733 ///
1734 /// type Bar = ❰ extern ❱ fn() -> u32;
1735 ///
1736 /// type Baz = ❰ extern r#"stdcall"# ❱ fn() -> bool;
1737 /// ```
1738 ///
1739 /// - [Extern blocks reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
1740 /// - [FFI function pointers reference](https://doc.rust-lang.org/reference/items/functions.html#functions)
1741 struct Abi { /*String*/ }
1742
1743 /// Expression statement.
1744 ///
1745 /// ```
1746 /// ❰ 42; ❱
1747 /// ❰ foo(); ❱
1748 /// ❰ (); ❱
1749 /// ❰ {}; ❱
1750 ///
1751 /// // constructions with trailing curly brace can omit the semicolon
1752 /// // but only when there are satements immediately after them (this is important!)
1753 /// ❰ if bool_cond { } ❱
1754 /// ❰ loop {} ❱
1755 /// ❰ somestatment; ❱
1756 /// ```
1757 ///
1758 /// [Reference](https://doc.rust-lang.org/reference/statements.html)
1759 struct ExprStmt: AttrsOwner { Expr, T![;] }
1760
1761 /// Let statement.
1762 ///
1763 /// ```
1764 /// ❰ #[attr] let foo; ❱
1765 /// ❰ let bar: u64; ❱
1766 /// ❰ let baz = 42; ❱
1767 /// ❰ let bruh: bool = true; ❱
1768 /// ```
1769 ///
1770 /// [Reference](https://doc.rust-lang.org/reference/statements.html#let-statements)
1771 struct LetStmt: AttrsOwner, TypeAscriptionOwner {
1772 T![let],
1773 Pat,
1774 T![=],
1775 initializer: Expr,
1776 T![;],
1777 }
1778
1779 /// Condition of `if` or `while` expression.
1780 ///
1781 /// ```
1782 /// if ❰ true ❱ {}
1783 /// if ❰ let Pat(foo) = bar ❱ {}
1784 ///
1785 /// while ❰ true ❱ {}
1786 /// while ❰ let Pat(baz) = bruh ❱ {}
1787 /// ```
1788 ///
1789 /// [If expression reference](https://doc.rust-lang.org/reference/expressions/if-expr.html)
1790 /// [While expression reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-loops)
1791 struct Condition { T![let], Pat, T![=], Expr }
1792
1793 /// Parameter list **declaration**.
1794 ///
1795 /// ```
1796 /// fn foo❰ (a: u32, b: bool) ❱ -> u32 {}
1797 /// let bar = ❰ |a, b| ❱ {};
1798 ///
1799 /// impl Baz {
1800 /// fn bruh❰ (&self, a: u32) ❱ {}
1801 /// }
1802 /// ```
1803 ///
1804 /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)ocs to codegen script
1805 struct ParamList { // FIXME: this node is used by closure expressions too, but hey use pipes instead of parens...
1806 T!['('],
1807 SelfParam,
1808 params: [Param],
1809 T![')']
1810 }
1811
1812 /// Self parameter **declaration**.
1813 ///
1814 /// ```
1815 /// impl Bruh {
1816 /// fn foo(❰ self ❱) {}
1817 /// fn bar(❰ &self ❱) {}
1818 /// fn baz(❰ &mut self ❱) {}
1819 /// fn blah<'a>(❰ &'a self ❱) {}
1820 /// fn blin(❰ self: Box<Self> ❱) {}
1821 /// }
1822 /// ```
1823 ///
1824 /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
1825 struct SelfParam: TypeAscriptionOwner, AttrsOwner { T![&], T![mut], T![lifetime], T![self] }
1826
1827 /// Parameter **declaration**.
1828 ///
1829 /// ```
1830 /// fn foo(❰ #[attr] Pat(bar): Pat(u32) ❱, ❰ #[attr] _: bool ❱) {}
1831 ///
1832 /// extern "C" {
1833 /// fn bar(❰ baz: u32 ❱, ❰ ... ❱) -> u32;
1834 /// }
1835 /// ```
1836 ///
1837 /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
1838 struct Param: TypeAscriptionOwner, AttrsOwner {
1839 Pat,
1840 T![...]
1841 }
1842
1843 /// Use declaration.
1844 ///
1845 /// ```
1846 /// ❰ #[attr] pub use foo; ❱
1847 /// ❰ use bar as baz; ❱
1848 /// ❰ use bruh::{self, bruuh}; ❱
1849 /// ❰ use { blin::blen, blah::* };
1850 /// ```
1851 ///
1852 /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
1853 struct UseItem: AttrsOwner, VisibilityOwner {
1854 T![use],
1855 UseTree,
1856 }
1857
1858 /// Use tree.
1859 ///
1860 /// ```
1861 /// pub use ❰ foo::❰ * ❱ ❱;
1862 /// use ❰ bar as baz ❱;
1863 /// use ❰ bruh::bruuh::{ ❰ self ❱, ❰ blin ❱ } ❱;
1864 /// use ❰ { ❰ blin::blen ❱ } ❱
1865 /// ```
1866 ///
1867 /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
1868 struct UseTree {
1869 Path, T![*], UseTreeList, Alias
1870 }
1871
1872 /// Item alias.
1873 /// Note: this is not the type alias.
1874 ///
1875 /// ```
1876 /// use foo ❰ as bar ❱;
1877 /// use baz::{bruh ❰ as _ ❱};
1878 /// extern crate bruuh ❰ as blin ❱;
1879 /// ```
1880 ///
1881 /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
1882 struct Alias: NameOwner { T![as] }
1883
1884 /// Sublist of use trees.
1885 ///
1886 /// ```
1887 /// use bruh::bruuh::❰ { ❰ self ❱, ❰ blin ❱ } ❱;
1888 /// use ❰ { blin::blen::❰ {} ❱ } ❱
1889 /// ```
1890 ///
1891 /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
1892 struct UseTreeList { T!['{'], use_trees: [UseTree], T!['}'] }
1893
1894 /// Extern crate item.
1895 ///
1896 /// ```
1897 /// ❰ #[attr] pub extern crate foo; ❱
1898 /// ❰ extern crate self as bar; ❱
1899 /// ```
1900 ///
1901 /// [Reference](https://doc.rust-lang.org/reference/items/extern-crates.html)
1902 struct ExternCrateItem: AttrsOwner, VisibilityOwner {
1903 T![extern], T![crate], NameRef, Alias,
1904 }
1905
1906 /// Call site arguments list.
1907 ///
1908 /// ```
1909 /// foo::<T, U>❰ (42, true) ❱;
1910 /// ```
1911 ///
1912 /// [Reference](https://doc.rust-lang.org/reference/expressions/call-expr.html)
1913 struct ArgList {
1914 T!['('],
1915 args: [Expr],
1916 T![')']
1917 }
1918
1919 /// Path to a symbol. Includes single identifier names and elaborate paths with
1920 /// generic parameters.
1921 ///
1922 /// ```
1923 /// (0..10).❰ ❰ collect ❱ ::<Vec<_>> ❱();
1924 /// ❰ ❰ ❰ Vec ❱ ::<u8> ❱ ::with_capacity ❱(1024);
1925 /// ❰ ❰ <❰ Foo ❱ as ❰ ❰ bar ❱ ::Bar ❱> ❱ ::baz ❱();
1926 /// ❰ ❰ <❰ bruh ❱> ❱ ::bruuh ❱();
1927 /// ```
1928 ///
1929 /// [Reference](https://doc.rust-lang.org/reference/paths.html)
1930 struct Path {
1931 segment: PathSegment,
1932 T![::],
1933 qualifier: Path,
1934 }
1935
1936 /// Segment of the path to a symbol.
1937 /// Only path segment of an absolute path holds the `::` token,
1938 /// all other `::` tokens that connect path segments reside under `Path` itself.`
1939 ///
1940 /// ```
1941 /// (0..10).❰ collect ❱ :: ❰ <Vec<_>> ❱();
1942 /// ❰ Vec ❱ :: ❰ <u8> ❱ :: ❰ with_capacity ❱(1024);
1943 /// ❰ <❰ Foo ❱ as ❰ bar ❱ :: ❰ Bar ❱> ❱ :: ❰ baz ❱();
1944 /// ❰ <❰ bruh ❱> ❱ :: ❰ bruuh ❱();
1945 ///
1946 /// // Note that only in this case `::` token is inlcuded:
1947 /// ❰ ::foo ❱;
1948 /// ```
1949 ///
1950 /// [Reference](https://doc.rust-lang.org/reference/paths.html)
1951 struct PathSegment {
1952 T![::], T![crate], T![self], T![super], T![<], NameRef, TypeArgList, ParamList, RetType, PathType, T![>]
1953 }
1954
1955 /// List of type arguments that are passed at generic instantiation site.
1956 ///
1957 /// ```
1958 /// type _ = Foo ❰ ::<'a, u64, Item = Bar, 42, {true}> ❱::Bar;
1959 ///
1960 /// Vec❰ ::<bool> ❱::();
1961 /// ```
1962 ///
1963 /// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
1964 struct TypeArgList {
1965 T![::],
1966 T![<],
1967 generic_args: [GenericArg],
1968 type_args: [TypeArg],
1969 lifetime_args: [LifetimeArg],
1970 assoc_type_args: [AssocTypeArg],
1971 const_args: [ConstArg],
1972 T![>]
1973 }
1974
1975 /// Type argument that is passed at generic instantiation site.
1976 ///
1977 /// ```
1978 /// type _ = Foo::<'a, ❰ u64 ❱, ❰ bool ❱, Item = Bar, 42>::Baz;
1979 /// ```
1980 ///
1981 /// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
1982 struct TypeArg { TypeRef }
1983
1984 /// Associated type argument that is passed at generic instantiation site.
1985 /// ```
1986 /// type Foo = Bar::<'a, u64, bool, ❰ Item = Baz ❱, 42>::Bruh;
1987 ///
1988 /// trait Bruh<T>: Iterator<❰ Item: Debug ❱> {}
1989 /// ```
1990 ///
1991 struct AssocTypeArg : TypeBoundsOwner { NameRef, T![=], TypeRef }
1992
1993 /// Lifetime argument that is passed at generic instantiation site.
1994 ///
1995 /// ```
1996 /// fn foo<'a>(s: &'a str) {
1997 /// bar::<❰ 'a ❱>(s);
1998 /// }
1999 /// ```
2000 ///
2001 /// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
2002 struct LifetimeArg { T![lifetime] }
2003
2004 /// Constant value argument that is passed at generic instantiation site.
2005 ///
2006 /// ```
2007 /// foo::<u32, ❰ { true } ❱>();
2008 ///
2009 /// bar::<❰ { 2 + 2} ❱>();
2010 /// ```
2011 ///
2012 /// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/2000-const-generics.md#declaring-a-const-parameter)
2013 struct ConstArg { Literal, BlockExpr }
2014
2015
2016 /// FIXME: (@edwin0cheng) Remove it to use ItemList instead
2017 /// https://github.com/rust-analyzer/rust-analyzer/pull/4083#discussion_r422666243
2018 ///
2019 /// [Reference](https://doc.rust-lang.org/reference/macros.html)
2020 struct MacroItems: ModuleItemOwner { }
2021
2022 /// FIXME: (@edwin0cheng) add some documentation here. As per the writing
2023 /// of this comment this ast node is not used.
2024 ///
2025 /// ```
2026 /// // FIXME: example here
2027 /// ```
2028 ///
2029 /// [Reference](https://doc.rust-lang.org/reference/macros.html)
2030 struct MacroStmts {
2031 statements: [Stmt],
2032 Expr,
2033 }
2034
2035 /// List of items in an extern block.
2036 ///
2037 /// ```
2038 /// extern "C" ❰
2039 /// {
2040 /// fn foo();
2041 /// static var: u32;
2042 /// }
2043 /// ❱
2044 /// ```
2045 ///
2046 /// [Reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
2047 struct ExternItemList: ModuleItemOwner {
2048 T!['{'],
2049 extern_items: [ExternItem],
2050 T!['}']
2051 }
2052
2053 /// Extern block.
2054 ///
2055 /// ```
2056 /// ❰
2057 /// extern "C" {
2058 /// fn foo();
2059 /// }
2060 /// ❱
2061 ///
2062 /// ```
2063 ///
2064 /// [Reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
2065 struct ExternBlock {
2066 Abi,
2067 ExternItemList
2068 }
2069
2070 /// Meta item in an attribute.
2071 ///
2072 /// ```
2073 /// #[❰ bar::baz = "42" ❱]
2074 /// #[❰ bruh(bruuh("true")) ❱]
2075 /// struct Foo;
2076 /// ```
2077 ///
2078 /// [Reference](https://doc.rust-lang.org/reference/attributes.html?highlight=meta,item#meta-item-attribute-syntax)
2079 struct MetaItem {
2080 Path, T![=], AttrInput, nested_meta_items: [MetaItem]
2081 }
2082
2083 /// Macro 2.0 definition.
2084 /// Their syntax is still WIP by rustc team...
2085 /// ```
2086 /// ❰
2087 /// macro foo { }
2088 /// ❱
2089 /// ```
2090 ///
2091 /// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/1584-macros.md)
2092 struct MacroDef {
2093 Name, TokenTree
2094 }
2095 },
2096 enums: ast_enums! {
2097 /// Any kind of nominal type definition.
2098 enum NominalDef: NameOwner, TypeParamsOwner, AttrsOwner {
2099 StructDef, EnumDef, UnionDef,
2100 }
2101
2102 /// Any kind of generic argument passed at instantiation site
2103 enum GenericArg {
2104 LifetimeArg,
2105 TypeArg,
2106 ConstArg,
2107 AssocTypeArg
2108 }
2109
2110 /// Any kind of construct valid in type context
2111 enum TypeRef {
2112 ParenType,
2113 TupleType,
2114 NeverType,
2115 PathType,
2116 PointerType,
2117 ArrayType,
2118 SliceType,
2119 ReferenceType,
2120 PlaceholderType,
2121 FnPointerType,
2122 ForType,
2123 ImplTraitType,
2124 DynTraitType,
2125 }
2126
2127 /// Any kind of top-level item that may appear in a module
2128 enum ModuleItem: NameOwner, AttrsOwner, VisibilityOwner {
2129 StructDef,
2130 UnionDef,
2131 EnumDef,
2132 FnDef,
2133 TraitDef,
2134 TypeAliasDef,
2135 ImplDef,
2136 UseItem,
2137 ExternCrateItem,
2138 ConstDef,
2139 StaticDef,
2140 Module,
2141 MacroCall,
2142 ExternBlock
2143 }
2144
2145
2146
2147 /// Any kind of item that may appear in an impl block
2148 ///
2149 /// // FIXME: impl blocks can also contain MacroCall
2150 enum AssocItem: NameOwner, AttrsOwner {
2151 FnDef, TypeAliasDef, ConstDef
2152 }
2153
2154 /// Any kind of item that may appear in an extern block
2155 ///
2156 /// // FIXME: extern blocks can also contain MacroCall
2157 enum ExternItem: NameOwner, AttrsOwner, VisibilityOwner {
2158 FnDef, StaticDef
2159 }
2160
2161 /// Any kind of expression
2162 enum Expr: AttrsOwner {
2163 TupleExpr,
2164 ArrayExpr,
2165 ParenExpr,
2166 PathExpr,
2167 LambdaExpr,
2168 IfExpr,
2169 LoopExpr,
2170 ForExpr,
2171 WhileExpr,
2172 ContinueExpr,
2173 BreakExpr,
2174 Label,
2175 BlockExpr,
2176 ReturnExpr,
2177 MatchExpr,
2178 RecordLit,
2179 CallExpr,
2180 IndexExpr,
2181 MethodCallExpr,
2182 FieldExpr,
2183 AwaitExpr,
2184 TryExpr,
2185 EffectExpr,
2186 CastExpr,
2187 RefExpr,
2188 PrefixExpr,
2189 RangeExpr,
2190 BinExpr,
2191 Literal,
2192 MacroCall,
2193 BoxExpr,
2194 }
2195
2196 /// Any kind of pattern
2197 enum Pat {
2198 OrPat,
2199 ParenPat,
2200 RefPat,
2201 BoxPat,
2202 BindPat,
2203 PlaceholderPat,
2204 DotDotPat,
2205 PathPat,
2206 RecordPat,
2207 TupleStructPat,
2208 TuplePat,
2209 SlicePat,
2210 RangePat,
2211 LiteralPat,
2212 MacroPat,
2213 }
2214
2215 /// Any kind of input to an attribute
2216 enum AttrInput { Literal, TokenTree }
2217
2218 /// Any kind of statement
2219 /// Note: there are no empty statements, these are just represented as
2220 /// bare semicolons without a dedicated statement ast node.
2221 enum Stmt {
2222 LetStmt,
2223 ExprStmt,
2224 // macro calls are parsed as expression statements
2225 }
2226
2227 /// Any kind of fields list (record or tuple field lists)
2228 enum FieldDefList {
2229 RecordFieldDefList,
2230 TupleFieldDefList,
2231 }
2232 },
2233 }
2234}
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index 5a18b3e2b..24e8be1fb 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -3,19 +3,27 @@
3//! Specifically, it generates the `SyntaxKind` enum and a number of newtype 3//! Specifically, it generates the `SyntaxKind` enum and a number of newtype
4//! wrappers around `SyntaxNode` which implement `ra_syntax::AstNode`. 4//! wrappers around `SyntaxNode` which implement `ra_syntax::AstNode`.
5 5
6use std::{collections::HashSet, fmt::Write}; 6use std::{
7 collections::{BTreeSet, HashSet},
8 fmt::Write,
9};
7 10
8use proc_macro2::{Punct, Spacing}; 11use proc_macro2::{Punct, Spacing};
9use quote::{format_ident, quote}; 12use quote::{format_ident, quote};
13use ungrammar::{Grammar, Rule};
10 14
11use crate::{ 15use crate::{
12 ast_src::{rust_ast, AstSrc, Field, FieldSrc, KindsSrc, KINDS_SRC}, 16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Field, FieldSrc, KindsSrc, KINDS_SRC},
13 codegen::{self, update, Mode}, 17 codegen::{self, update, Mode},
14 project_root, Result, 18 project_root, Result,
15}; 19};
16 20
17pub fn generate_syntax(mode: Mode) -> Result<()> { 21pub fn generate_syntax(mode: Mode) -> Result<()> {
18 let ast = rust_ast(); 22 let grammar = include_str!("rust.ungram")
23 .parse::<Grammar>()
24 .unwrap_or_else(|err| panic!("\n \x1b[91merror\x1b[0m: {}\n", err));
25 let ast = lower(&grammar);
26
19 let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS); 27 let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS);
20 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; 28 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?;
21 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; 29 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?;
@@ -215,7 +223,9 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> Result<String> {
215 .map(|kind| to_pascal_case(kind)) 223 .map(|kind| to_pascal_case(kind))
216 .filter(|name| !defined_nodes.iter().any(|&it| it == name)) 224 .filter(|name| !defined_nodes.iter().any(|&it| it == name))
217 { 225 {
218 eprintln!("Warning: node {} not defined in ast source", node); 226 drop(node)
227 // TODO: restore this
228 // eprintln!("Warning: node {} not defined in ast source", node);
219 } 229 }
220 230
221 let ast = quote! { 231 let ast = quote! {
@@ -414,6 +424,10 @@ fn to_pascal_case(s: &str) -> String {
414 buf 424 buf
415} 425}
416 426
427fn pluralize(s: &str) -> String {
428 format!("{}s", s)
429}
430
417impl Field { 431impl Field {
418 fn is_many(&self) -> bool { 432 fn is_many(&self) -> bool {
419 matches!(self, Field::Node { src: FieldSrc::Many(_), .. }) 433 matches!(self, Field::Node { src: FieldSrc::Many(_), .. })
@@ -449,6 +463,7 @@ impl Field {
449 "." => "dot", 463 "." => "dot",
450 ".." => "dotdot", 464 ".." => "dotdot",
451 "..." => "dotdotdot", 465 "..." => "dotdotdot",
466 "..=" => "dotdoteq",
452 "=>" => "fat_arrow", 467 "=>" => "fat_arrow",
453 "@" => "at", 468 "@" => "at",
454 ":" => "colon", 469 ":" => "colon",
@@ -475,3 +490,204 @@ impl Field {
475 } 490 }
476 } 491 }
477} 492}
493
494fn lower(grammar: &Grammar) -> AstSrc {
495 let mut res = AstSrc::default();
496 res.tokens = vec!["Whitespace".into(), "Comment".into(), "String".into(), "RawString".into()];
497
498 let nodes = grammar
499 .iter()
500 .filter(|&node| match grammar[node].rule {
501 Rule::Node(it) if it == node => false,
502 _ => true,
503 })
504 .collect::<Vec<_>>();
505
506 for &node in &nodes {
507 let name = grammar[node].name.clone();
508 let rule = &grammar[node].rule;
509 match lower_enum(grammar, rule) {
510 Some(variants) => {
511 let enum_src = AstEnumSrc { doc: Vec::new(), name, traits: Vec::new(), variants };
512 res.enums.push(enum_src);
513 }
514 None => {
515 let mut fields = Vec::new();
516 lower_rule(&mut fields, grammar, rule);
517 res.nodes.push(AstNodeSrc { doc: Vec::new(), name, traits: Vec::new(), fields });
518 }
519 }
520 }
521
522 deduplicate_fields(&mut res);
523 extract_enums(&mut res);
524 extract_struct_traits(&mut res);
525 extract_enum_traits(&mut res);
526 res
527}
528
529fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> {
530 let alternatives = match rule {
531 Rule::Alt(it) => it,
532 _ => return None,
533 };
534 let mut variants = Vec::new();
535 for alternative in alternatives {
536 match alternative {
537 Rule::Node(it) => variants.push(grammar[*it].name.clone()),
538 _ => return None,
539 }
540 }
541 Some(variants)
542}
543
544fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) {
545 match rule {
546 Rule::Node(node) => {
547 let field = Field::Node { name: grammar[*node].name.clone(), src: FieldSrc::Shorthand };
548 acc.push(field);
549 }
550 Rule::Token(token) => {
551 let mut name = grammar[*token].name.clone();
552 if name != "int_number" && name != "string" {
553 if "[]{}()".contains(&name) {
554 name = format!("'{}'", name);
555 }
556 let field = Field::Token(name);
557 acc.push(field);
558 }
559 }
560 Rule::Rep(inner) => {
561 if let Rule::Node(node) = &**inner {
562 let name = grammar[*node].name.clone();
563 let label = pluralize(&to_lower_snake_case(&name));
564 let field = Field::Node { name: label.clone(), src: FieldSrc::Many(name) };
565 acc.push(field);
566 return;
567 }
568 todo!("{:?}", rule)
569 }
570 Rule::Labeled { label, rule } => {
571 let node = match &**rule {
572 Rule::Rep(inner) | Rule::Opt(inner) => match &**inner {
573 Rule::Node(node) => node,
574 _ => todo!("{:?}", rule),
575 },
576 Rule::Node(node) => node,
577 _ => todo!("{:?}", rule),
578 };
579 let field = Field::Node {
580 name: label.clone(),
581 src: match &**rule {
582 Rule::Rep(_) => FieldSrc::Many(grammar[*node].name.clone()),
583 _ => FieldSrc::Optional(grammar[*node].name.clone()),
584 },
585 };
586 acc.push(field);
587 }
588 Rule::Seq(rules) | Rule::Alt(rules) => {
589 for rule in rules {
590 lower_rule(acc, grammar, rule)
591 }
592 }
593 Rule::Opt(rule) => lower_rule(acc, grammar, rule),
594 }
595}
596
597fn deduplicate_fields(ast: &mut AstSrc) {
598 eprintln!();
599 for node in &mut ast.nodes {
600 let mut i = 0;
601 'outer: while i < node.fields.len() {
602 for j in 0..i {
603 let f1 = &node.fields[i];
604 let f2 = &node.fields[j];
605 if f1 == f2 {
606 node.fields.remove(i);
607 continue 'outer;
608 }
609 }
610 i += 1;
611 }
612 }
613}
614
615fn extract_enums(ast: &mut AstSrc) {
616 for node in &mut ast.nodes {
617 for enm in &ast.enums {
618 let mut to_remove = Vec::new();
619 for (i, field) in node.fields.iter().enumerate() {
620 let ty = field.ty().to_string();
621 if enm.variants.iter().any(|it| it == &ty) {
622 to_remove.push(i);
623 }
624 }
625 if to_remove.len() == enm.variants.len() {
626 node.remove_field(to_remove);
627 node.fields.push(Field::Node { name: enm.name.clone(), src: FieldSrc::Shorthand });
628 }
629 }
630 }
631}
632
633fn extract_struct_traits(ast: &mut AstSrc) {
634 let traits: &[(&str, &[&str])] = &[
635 ("AttrsOwner", &["attrs"]),
636 ("NameOwner", &["name"]),
637 ("VisibilityOwner", &["visibility"]),
638 ("TypeParamsOwner", &["type_param_list", "where_clause"]),
639 ("TypeBoundsOwner", &["type_bound_list", "colon_token"]),
640 ("ModuleItemOwner", &["items"]),
641 ("TypeAscriptionOwner", &["ascribed_type"]),
642 ("LoopBodyOwner", &["label", "loop_body"]),
643 ("ArgListOwner", &["arg_list"]),
644 ];
645
646 for node in &mut ast.nodes {
647 for (name, methods) in traits {
648 extract_struct_trait(node, name, methods);
649 }
650 }
651}
652
653fn extract_struct_trait(node: &mut AstNodeSrc, trait_name: &str, methods: &[&str]) {
654 let mut to_remove = Vec::new();
655 for (i, field) in node.fields.iter().enumerate() {
656 let method_name = field.method_name().to_string();
657 if methods.iter().any(|&it| it == &method_name) {
658 to_remove.push(i);
659 }
660 }
661 if to_remove.len() == methods.len() {
662 node.traits.push(trait_name.to_string());
663 node.remove_field(to_remove);
664 }
665}
666
667fn extract_enum_traits(ast: &mut AstSrc) {
668 for enm in &mut ast.enums {
669 let nodes = &ast.nodes;
670 let mut variant_traits = enm
671 .variants
672 .iter()
673 .map(|var| nodes.iter().find(|it| &it.name == var).unwrap())
674 .map(|node| node.traits.iter().cloned().collect::<BTreeSet<_>>());
675
676 let mut enum_traits = match variant_traits.next() {
677 Some(it) => it,
678 None => continue,
679 };
680 for traits in variant_traits {
681 enum_traits = enum_traits.intersection(&traits).cloned().collect();
682 }
683 enm.traits = enum_traits.into_iter().collect();
684 }
685}
686
687impl AstNodeSrc {
688 fn remove_field(&mut self, to_remove: Vec<usize>) {
689 to_remove.into_iter().rev().for_each(|idx| {
690 self.fields.remove(idx);
691 });
692 }
693}
diff --git a/xtask/src/codegen/rust.ungram b/xtask/src/codegen/rust.ungram
new file mode 100644
index 000000000..8a3eb7b29
--- /dev/null
+++ b/xtask/src/codegen/rust.ungram
@@ -0,0 +1,529 @@
1SourceFile =
2 Attr*
3 items:ModuleItem*
4
5FnDef =
6 Attr* Visibility? Abi? 'const' 'default' 'async' 'unsafe' 'fn' Name TypeParamList?
7 ParamList RetType?
8 WhereClause?
9 (body:BlockExpr | ';')
10
11RetType =
12 '->' TypeRef
13
14StructDef =
15 Attr* Visibility? 'struct' Name TypeParamList? (
16 WhereClause? (RecordFieldDefList | ';')
17 | TupleFieldDefList WhereClause? ';'
18 )
19
20UnionDef =
21 Attr* Visibility? 'union' Name TypeParamList? WhereClause?
22 RecordFieldDefList
23
24RecordFieldDefList =
25 '{' fields:RecordFieldDef* '}'
26
27RecordFieldDef =
28 Attr* Visibility? Name ':' ascribed_type:TypeRef
29
30TupleFieldDefList =
31 '(' fields:TupleFieldDef* ')'
32
33TupleFieldDef =
34 Attr* Visibility? Name TypeRef
35
36FieldDefList =
37 RecordFieldDefList
38| TupleFieldDefList
39
40EnumDef =
41 Attr* Visibility? 'enum' Name TypeParamList? WhereClause?
42 variant_list:EnumVariantList
43
44EnumVariantList =
45 '{' variants:EnumVariant* '}'
46
47EnumVariant =
48 Attr* Visibility? Name FieldDefList ('=' Expr)?
49
50TraitDef =
51 Attr* Visibility? 'unsafe'? 'auto'? 'trait' Name TypeParamList
52 (':' TypeBoundList?)? WhereClause
53 ItemList
54
55Module =
56 Attr* Visibility? 'mod' Name
57 (ItemList | ';')
58
59ItemList =
60 '{'
61 AssocItem*
62 items:ModuleItem*
63 '}'
64
65ConstDef =
66 Attr* Visibility? 'default'? 'const' Name ':' ascribed_type:TypeRef
67 '=' body:Expr ';'
68
69StaticDef =
70 Attr* Visibility? 'static'? 'mut'? 'static' Name ':' ascribed_type:TypeRef
71 '=' body:Expr ';'
72
73TypeAliasDef =
74 Attr* Visibility? 'default'? 'type' Name TypeParamList? WhereClause? (':' TypeBoundList?)?
75 '=' TypeRef ';'
76
77ImplDef =
78 Attr* Visibility? 'const'? 'default'? 'unsafe'? 'impl' TypeParamList? '!'? 'for'
79 WhereClause?
80 ItemList
81
82ParenType =
83 '(' TypeRef ')'
84
85TupleType =
86 '(' fields:TypeRef* ')'
87
88NeverType =
89 '!'
90
91PathType =
92 Path
93
94PointerType =
95 '*' ('const' | 'mut') TypeRef
96
97ArrayType =
98 '[' TypeRef ';' Expr ']'
99
100SliceType =
101 '[' TypeRef ']'
102
103ReferenceType =
104 '&' 'lifetime'? 'mut'? TypeRef
105
106PlaceholderType =
107 '_'
108
109FnPointerType =
110 Abi 'unsafe'? 'fn' ParamList RetType?
111
112ForType =
113 'for' TypeParamList TypeRef
114
115ImplTraitType =
116 'impl' TypeBoundList
117
118DynTraitType =
119 'dyn' TypeBoundList
120
121TupleExpr =
122 Attr* '(' Expr* ')'
123
124ArrayExpr =
125 Attr* '[' (Expr* | Expr ';' Expr) ']'
126
127ParenExpr =
128 Attr* '(' Expr ')'
129
130PathExpr =
131 Path
132
133LambdaExpr =
134 Attr* 'static'? 'async'? 'move'? ParamList RetType?
135 body:Expr
136
137IfExpr =
138 Attr* 'if' Condition
139
140Condition =
141 'let' Pat '=' Expr
142| Expr
143
144EffectExpr =
145 Attr* Label? ('try' | 'unsafe' | 'async') BlockExpr
146
147LoopExpr =
148 Attr* Label? 'loop'
149 loop_body:BlockExpr?
150
151ForExpr =
152 Attr* Label? 'for' Pat 'in' iterable:Expr
153 loop_body:BlockExpr?
154
155WhileExpr =
156 Attr* Label? 'while' Condition
157 loop_body:BlockExpr?
158
159ContinueExpr =
160 Attr* 'continue' 'lifetime'?
161
162BreakExpr =
163 Attr* 'break' 'lifetime'? Expr?
164
165Label =
166 'lifetime'
167
168BlockExpr =
169 Attr* Label
170 '{'
171 items:ModuleItem*
172 statements:Stmt*
173 Expr?
174 '}'
175
176ReturnExpr =
177 Attr* 'return' Expr
178
179CallExpr =
180 Attr* Expr ArgList
181
182MethodCallExpr =
183 Attr* Expr '.' NameRef TypeArgList? ArgList
184
185ArgList =
186 '(' args:Expr* ')'
187
188FieldExpr =
189 Attr* Expr '.' NameRef
190
191IndexExpr =
192 Attr* '[' ']'
193
194AwaitExpr =
195 Attr* Expr '.' 'await'
196
197TryExpr =
198 Attr* Expr '?'
199
200CastExpr =
201 Attr* Expr 'as' TypeRef
202
203RefExpr =
204 Attr* '&' ('raw' | 'mut' | 'const') Expr
205
206PrefixExpr =
207 Attr* Expr
208
209BoxExpr =
210 Attr* 'box' Expr
211
212RangeExpr =
213 Attr*
214
215BinExpr =
216 Attr*
217
218Literal =
219 'int_number'
220
221MatchExpr =
222 Attr* 'match' Expr MatchArmList
223
224MatchArmList =
225 '{' arms:MatchArm* '}'
226
227MatchArm =
228 Attr* Pat guard:MatchGuard? '=>' Expr
229
230MatchGuard =
231 'if' Expr
232
233RecordLit =
234 Path RecordFieldList
235
236RecordFieldList =
237 '{'
238 fields:RecordField*
239 ('..' spread:Expr)?
240 '}'
241
242RecordField =
243 Attr* NameRef (':' Expr)?
244
245OrPat =
246 Pat*
247
248ParenPat =
249 '(' Pat ')'
250
251RefPat =
252 '&' 'mut'? Pat
253
254BoxPat =
255 'box' Path
256
257BindPat =
258 Attr* 'ref'? 'mut'? Name ('@' Pat)?
259
260PlaceholderPat =
261 '_'
262
263DotDotPat =
264 '..'
265
266PathPat =
267 Path
268
269SlicePat =
270 '[' args:Pat* ']'
271
272RangePat =
273 '..' | '..='
274
275LiteralPat =
276 Literal
277
278MacroPat =
279 MacroCall
280
281RecordPat =
282 Path RecordFieldPatList
283
284RecordFieldPatList =
285 '{'
286 record_field_pats:RecordFieldPat*
287 BindPat*
288 '..'?
289 '}'
290
291RecordFieldPat =
292 Attr* NameRef ':' Pat
293
294TupleStructPat =
295 Path '(' args:Pat* ')'
296
297TuplePat =
298 '(' args:Pat* ')'
299
300Visibility =
301 'pub' ('(' 'super' | 'self' | 'crate' | 'in' Path ')')?
302
303Name =
304 'ident'
305
306NameRef =
307 'ident' | 'int_number'
308
309MacroCall =
310 Attr* Path '!' Name? TokenTree ';'?
311
312MacroDef =
313 Name TokenTree
314
315TokenTree =
316 '(' ')' | '{' '}' | '[' ']'
317
318MacroItems =
319 items:ModuleItem*
320
321MacroStmts =
322 statements:Stmt*
323 Expr?
324
325Attr =
326 '#' '!'? '[' Path ('=' input:AttrInput)? ']'
327
328TypeParamList =
329 '<'
330 TypeParam*
331 LifetimeParam*
332 ConstParam*
333 '>'
334
335TypeParam =
336 Attr* Name (':' TypeBoundList?)?
337 ('=' default_type:TypeRef)?
338
339ConstParam =
340 Attr* 'const' Name ':' ascribed_type:TypeRef
341 ('=' default_val:Expr)?
342
343LifetimeParam =
344 Attr* 'lifetime'
345
346TypeBound =
347 'lifetime' | 'const'? TypeRef
348
349TypeBoundList =
350 bounds:TypeBound*
351
352WherePred =
353 ('for' TypeParamList)? ('lifetime' | TypeRef) ':' TypeBoundList
354
355WhereClause =
356 'where' predicates:WherePred*
357
358Abi =
359 'string'
360
361ExprStmt =
362 Attr* Expr ';'
363
364LetStmt =
365 Attr* 'let' Pat (':' ascribed_type:TypeRef)
366 '=' initializer:Expr ';'
367
368ParamList =
369 '(' SelfParam Param* ')'
370
371SelfParam =
372 Attr* ('&' 'lifetime'?)? 'mut'? 'self' (':' ascribed_type:TypeRef)
373
374Param =
375 Attr* Pat (':' ascribed_type:TypeRef)
376| '...'
377
378UseItem =
379 Attr* Visibility? 'use' UseTree ';'
380
381UseTree =
382 Path ('::' ('*' | UseTreeList)) Alias?
383
384UseTreeList =
385 '{' UseTree* '}'
386
387Alias =
388 'as' Name
389
390ExternCrateItem =
391 Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Alias? ';'
392
393Path =
394 (qualifier:Path '::')? segment:PathSegment
395
396PathSegment =
397 '::' | 'crate' | 'self' | 'super'
398| '<' NameRef TypeArgList ParamList RetType PathType '>'
399
400TypeArgList =
401 '::'? '<'
402 TypeArg*
403 LifetimeArg*
404 AssocTypeArg*
405 ConstArg*
406 '>'
407
408TypeArg =
409 TypeRef
410
411AssocTypeArg =
412 NameRef (':' TypeBoundList | '=' TypeRef)
413
414LifetimeArg =
415 'lifetime'
416
417ConstArg =
418 Literal | BlockExpr BlockExpr
419
420ExternBlock =
421 Attr* Abi ExternItemList
422
423ExternItemList =
424 '{' extern_items:ExternItem* '}'
425
426MetaItem =
427 Path '=' AttrInput nested_meta_items:MetaItem*
428
429NominalDef =
430 StructDef
431| EnumDef
432| UnionDef
433
434TypeRef =
435 ParenType
436| TupleType
437| NeverType
438| PathType
439| PointerType
440| ArrayType
441| SliceType
442| ReferenceType
443| PlaceholderType
444| FnPointerType
445| ForType
446| ImplTraitType
447| DynTraitType
448
449AssocItem =
450 FnDef
451| TypeAliasDef
452| ConstDef
453
454ExternItem =
455 FnDef | StaticDef
456
457ModuleItem =
458 StructDef
459| UnionDef
460| EnumDef
461| FnDef
462| TraitDef
463| TypeAliasDef
464| ImplDef
465| UseItem
466| ExternCrateItem
467| ConstDef
468| StaticDef
469| Module
470| MacroCall
471| ExternBlock
472
473AttrInput =
474 Literal
475| TokenTree
476
477Stmt =
478 LetStmt
479| ExprStmt
480
481Pat =
482 OrPat
483| ParenPat
484| RefPat
485| BoxPat
486| BindPat
487| PlaceholderPat
488| DotDotPat
489| PathPat
490| RecordPat
491| TupleStructPat
492| TuplePat
493| SlicePat
494| RangePat
495| LiteralPat
496| MacroPat
497
498Expr =
499 TupleExpr
500| ArrayExpr
501| ParenExpr
502| PathExpr
503| LambdaExpr
504| IfExpr
505| LoopExpr
506| ForExpr
507| WhileExpr
508| ContinueExpr
509| BreakExpr
510| Label
511| BlockExpr
512| ReturnExpr
513| MatchExpr
514| RecordLit
515| CallExpr
516| IndexExpr
517| MethodCallExpr
518| FieldExpr
519| AwaitExpr
520| TryExpr
521| EffectExpr
522| CastExpr
523| RefExpr
524| PrefixExpr
525| RangeExpr
526| BinExpr
527| Literal
528| MacroCall
529| BoxExpr