diff options
Diffstat (limited to 'xtask/src')
-rw-r--r-- | xtask/src/ast_src.rs | 114 | ||||
-rw-r--r-- | xtask/src/codegen.rs | 1 | ||||
-rw-r--r-- | xtask/src/codegen/gen_syntax.rs | 182 |
3 files changed, 59 insertions, 238 deletions
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs index f9cd12d0d..554afc76a 100644 --- a/xtask/src/ast_src.rs +++ b/xtask/src/ast_src.rs | |||
@@ -227,7 +227,6 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc { | |||
227 | pub(crate) struct AstSrc<'a> { | 227 | pub(crate) struct AstSrc<'a> { |
228 | pub(crate) nodes: &'a [AstNodeSrc<'a>], | 228 | pub(crate) nodes: &'a [AstNodeSrc<'a>], |
229 | pub(crate) enums: &'a [AstEnumSrc<'a>], | 229 | pub(crate) enums: &'a [AstEnumSrc<'a>], |
230 | pub(crate) token_enums: &'a [AstEnumSrc<'a>], | ||
231 | } | 230 | } |
232 | 231 | ||
233 | pub(crate) struct AstNodeSrc<'a> { | 232 | pub(crate) struct AstNodeSrc<'a> { |
@@ -415,11 +414,11 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
415 | struct TupleType { T!['('], fields: [TypeRef], T![')'] } | 414 | struct TupleType { T!['('], fields: [TypeRef], T![')'] } |
416 | struct NeverType { T![!] } | 415 | struct NeverType { T![!] } |
417 | struct PathType { Path } | 416 | struct PathType { Path } |
418 | struct PointerType { Star, T![const], T![mut], TypeRef } | 417 | struct PointerType { T![*], T![const], T![mut], TypeRef } |
419 | struct ArrayType { T!['['], TypeRef, T![;], Expr, T![']'] } | 418 | struct ArrayType { T!['['], TypeRef, T![;], Expr, T![']'] } |
420 | struct SliceType { T!['['], TypeRef, T![']'] } | 419 | struct SliceType { T!['['], TypeRef, T![']'] } |
421 | struct ReferenceType { Amp, Lifetime, T![mut], TypeRef } | 420 | struct ReferenceType { T![&], T![lifetime], T![mut], TypeRef } |
422 | struct PlaceholderType { Underscore } | 421 | struct PlaceholderType { T![_] } |
423 | struct FnPointerType { Abi, T![unsafe], T![fn], ParamList, RetType } | 422 | struct FnPointerType { Abi, T![unsafe], T![fn], ParamList, RetType } |
424 | struct ForType { T![for], TypeParamList, TypeRef } | 423 | struct ForType { T![for], TypeParamList, TypeRef } |
425 | struct ImplTraitType: TypeBoundsOwner { T![impl] } | 424 | struct ImplTraitType: TypeBoundsOwner { T![impl] } |
@@ -447,33 +446,33 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
447 | iterable: Expr, | 446 | iterable: Expr, |
448 | } | 447 | } |
449 | struct WhileExpr: AttrsOwner, LoopBodyOwner { T![while], Condition } | 448 | struct WhileExpr: AttrsOwner, LoopBodyOwner { T![while], Condition } |
450 | struct ContinueExpr: AttrsOwner { T![continue], Lifetime } | 449 | struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] } |
451 | struct BreakExpr: AttrsOwner { T![break], Lifetime, Expr } | 450 | struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr } |
452 | struct Label { Lifetime } | 451 | struct Label { T![lifetime] } |
453 | struct BlockExpr: AttrsOwner { Label, T![unsafe], Block } | 452 | struct BlockExpr: AttrsOwner { Label, T![unsafe], Block } |
454 | struct ReturnExpr: AttrsOwner { Expr } | 453 | struct ReturnExpr: AttrsOwner { Expr } |
455 | struct CallExpr: ArgListOwner { Expr } | 454 | struct CallExpr: ArgListOwner { Expr } |
456 | struct MethodCallExpr: AttrsOwner, ArgListOwner { | 455 | struct MethodCallExpr: AttrsOwner, ArgListOwner { |
457 | Expr, Dot, NameRef, TypeArgList, | 456 | Expr, T![.], NameRef, TypeArgList, |
458 | } | 457 | } |
459 | struct IndexExpr: AttrsOwner { T!['['], T![']'] } | 458 | struct IndexExpr: AttrsOwner { T!['['], T![']'] } |
460 | struct FieldExpr: AttrsOwner { Expr, Dot, NameRef } | 459 | struct FieldExpr: AttrsOwner { Expr, T![.], NameRef } |
461 | struct AwaitExpr: AttrsOwner { Expr, Dot, T![await] } | 460 | struct AwaitExpr: AttrsOwner { Expr, T![.], T![await] } |
462 | struct TryExpr: AttrsOwner { T![try], Expr } | 461 | struct TryExpr: AttrsOwner { T![try], Expr } |
463 | struct CastExpr: AttrsOwner { Expr, T![as], TypeRef } | 462 | struct CastExpr: AttrsOwner { Expr, T![as], TypeRef } |
464 | struct RefExpr: AttrsOwner { Amp, T![raw], T![mut], Expr } | 463 | struct RefExpr: AttrsOwner { T![&], T![raw], T![mut], Expr } |
465 | struct PrefixExpr: AttrsOwner { PrefixOp, Expr } | 464 | struct PrefixExpr: AttrsOwner { /*PrefixOp,*/ Expr } |
466 | struct BoxExpr: AttrsOwner { T![box], Expr } | 465 | struct BoxExpr: AttrsOwner { T![box], Expr } |
467 | struct RangeExpr: AttrsOwner { RangeOp } | 466 | struct RangeExpr: AttrsOwner { /*RangeOp*/ } |
468 | struct BinExpr: AttrsOwner { /*BinOp*/ } | 467 | struct BinExpr: AttrsOwner { /*BinOp*/ } |
469 | struct Literal { LiteralToken } | 468 | struct Literal { /*LiteralToken*/ } |
470 | 469 | ||
471 | struct MatchExpr: AttrsOwner { T![match], Expr, MatchArmList } | 470 | struct MatchExpr: AttrsOwner { T![match], Expr, MatchArmList } |
472 | struct MatchArmList: AttrsOwner { T!['{'], arms: [MatchArm], T!['}'] } | 471 | struct MatchArmList: AttrsOwner { T!['{'], arms: [MatchArm], T!['}'] } |
473 | struct MatchArm: AttrsOwner { | 472 | struct MatchArm: AttrsOwner { |
474 | pat: Pat, | 473 | pat: Pat, |
475 | guard: MatchGuard, | 474 | guard: MatchGuard, |
476 | FatArrow, | 475 | T![=>], |
477 | Expr, | 476 | Expr, |
478 | } | 477 | } |
479 | struct MatchGuard { T![if], Expr } | 478 | struct MatchGuard { T![if], Expr } |
@@ -482,22 +481,22 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
482 | struct RecordFieldList { | 481 | struct RecordFieldList { |
483 | T!['{'], | 482 | T!['{'], |
484 | fields: [RecordField], | 483 | fields: [RecordField], |
485 | Dotdot, | 484 | T![..], |
486 | spread: Expr, | 485 | spread: Expr, |
487 | T!['}'] | 486 | T!['}'] |
488 | } | 487 | } |
489 | struct RecordField: AttrsOwner { NameRef, Colon, Expr } | 488 | struct RecordField: AttrsOwner { NameRef, T![:], Expr } |
490 | 489 | ||
491 | struct OrPat { pats: [Pat] } | 490 | struct OrPat { pats: [Pat] } |
492 | struct ParenPat { T!['('], Pat, T![')'] } | 491 | struct ParenPat { T!['('], Pat, T![')'] } |
493 | struct RefPat { Amp, T![mut], Pat } | 492 | struct RefPat { T![&], T![mut], Pat } |
494 | struct BoxPat { T![box], Pat } | 493 | struct BoxPat { T![box], Pat } |
495 | struct BindPat: AttrsOwner, NameOwner { T![ref], T![mut], At, Pat } | 494 | struct BindPat: AttrsOwner, NameOwner { T![ref], T![mut], T![@], Pat } |
496 | struct PlaceholderPat { Underscore } | 495 | struct PlaceholderPat { T![_] } |
497 | struct DotDotPat { Dotdot } | 496 | struct DotDotPat { T![..] } |
498 | struct PathPat { Path } | 497 | struct PathPat { Path } |
499 | struct SlicePat { T!['['], args: [Pat], T![']'] } | 498 | struct SlicePat { T!['['], args: [Pat], T![']'] } |
500 | struct RangePat { RangeSeparator } | 499 | struct RangePat { /*RangeSeparator*/ } |
501 | struct LiteralPat { Literal } | 500 | struct LiteralPat { Literal } |
502 | struct MacroPat { MacroCall } | 501 | struct MacroPat { MacroCall } |
503 | 502 | ||
@@ -507,30 +506,30 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
507 | pats: [RecordInnerPat], | 506 | pats: [RecordInnerPat], |
508 | record_field_pats: [RecordFieldPat], | 507 | record_field_pats: [RecordFieldPat], |
509 | bind_pats: [BindPat], | 508 | bind_pats: [BindPat], |
510 | Dotdot, | 509 | T![..], |
511 | T!['}'] | 510 | T!['}'] |
512 | } | 511 | } |
513 | struct RecordFieldPat: AttrsOwner, NameOwner { Colon, Pat } | 512 | struct RecordFieldPat: AttrsOwner, NameOwner { T![:], Pat } |
514 | 513 | ||
515 | struct TupleStructPat { Path, T!['('], args: [Pat], T![')'] } | 514 | struct TupleStructPat { Path, T!['('], args: [Pat], T![')'] } |
516 | struct TuplePat { T!['('], args: [Pat], T![')'] } | 515 | struct TuplePat { T!['('], args: [Pat], T![')'] } |
517 | 516 | ||
518 | struct Visibility { T![pub], T![super], T![self], T![crate] } | 517 | struct Visibility { T![pub], T![super], T![self], T![crate] } |
519 | struct Name { Ident } | 518 | struct Name { T![ident] } |
520 | struct NameRef { NameRefToken } | 519 | struct NameRef { /*NameRefToken*/ } |
521 | 520 | ||
522 | struct MacroCall: NameOwner, AttrsOwner,DocCommentsOwner { | 521 | struct MacroCall: NameOwner, AttrsOwner,DocCommentsOwner { |
523 | Path, T![!], TokenTree, T![;] | 522 | Path, T![!], TokenTree, T![;] |
524 | } | 523 | } |
525 | struct Attr { Pound, T![!], T!['['], Path, T![=], input: AttrInput, T![']'] } | 524 | struct Attr { T![#], T![!], T!['['], Path, T![=], input: AttrInput, T![']'] } |
526 | struct TokenTree {} | 525 | struct TokenTree {} |
527 | struct TypeParamList { | 526 | struct TypeParamList { |
528 | LAngle, | 527 | T![<], |
529 | generic_params: [GenericParam], | 528 | generic_params: [GenericParam], |
530 | type_params: [TypeParam], | 529 | type_params: [TypeParam], |
531 | lifetime_params: [LifetimeParam], | 530 | lifetime_params: [LifetimeParam], |
532 | const_params: [ConstParam], | 531 | const_params: [ConstParam], |
533 | RAngle | 532 | T![>] |
534 | } | 533 | } |
535 | struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner { | 534 | struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner { |
536 | T![=], | 535 | T![=], |
@@ -540,12 +539,12 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
540 | T![=], | 539 | T![=], |
541 | default_val: Expr, | 540 | default_val: Expr, |
542 | } | 541 | } |
543 | struct LifetimeParam: AttrsOwner { Lifetime} | 542 | struct LifetimeParam: AttrsOwner { T![lifetime] } |
544 | struct TypeBound { Lifetime, /* Question, */ T![const], /* Question, */ TypeRef} | 543 | struct TypeBound { T![lifetime], /* Question, */ T![const], /* Question, */ TypeRef} |
545 | struct TypeBoundList { bounds: [TypeBound] } | 544 | struct TypeBoundList { bounds: [TypeBound] } |
546 | struct WherePred: TypeBoundsOwner { Lifetime, TypeRef } | 545 | struct WherePred: TypeBoundsOwner { T![lifetime], TypeRef } |
547 | struct WhereClause { T![where], predicates: [WherePred] } | 546 | struct WhereClause { T![where], predicates: [WherePred] } |
548 | struct Abi { String } | 547 | struct Abi { /*String*/ } |
549 | struct ExprStmt: AttrsOwner { Expr, T![;] } | 548 | struct ExprStmt: AttrsOwner { Expr, T![;] } |
550 | struct LetStmt: AttrsOwner, TypeAscriptionOwner { | 549 | struct LetStmt: AttrsOwner, TypeAscriptionOwner { |
551 | T![let], | 550 | T![let], |
@@ -567,17 +566,17 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
567 | params: [Param], | 566 | params: [Param], |
568 | T![')'] | 567 | T![')'] |
569 | } | 568 | } |
570 | struct SelfParam: TypeAscriptionOwner, AttrsOwner { Amp, Lifetime, T![self] } | 569 | struct SelfParam: TypeAscriptionOwner, AttrsOwner { T![&], T![lifetime], T![self] } |
571 | struct Param: TypeAscriptionOwner, AttrsOwner { | 570 | struct Param: TypeAscriptionOwner, AttrsOwner { |
572 | Pat, | 571 | Pat, |
573 | Dotdotdot | 572 | T![...] |
574 | } | 573 | } |
575 | struct UseItem: AttrsOwner, VisibilityOwner { | 574 | struct UseItem: AttrsOwner, VisibilityOwner { |
576 | T![use], | 575 | T![use], |
577 | UseTree, | 576 | UseTree, |
578 | } | 577 | } |
579 | struct UseTree { | 578 | struct UseTree { |
580 | Path, Star, UseTreeList, Alias | 579 | Path, T![*], UseTreeList, Alias |
581 | } | 580 | } |
582 | struct Alias: NameOwner { T![as] } | 581 | struct Alias: NameOwner { T![as] } |
583 | struct UseTreeList { T!['{'], use_trees: [UseTree], T!['}'] } | 582 | struct UseTreeList { T!['{'], use_trees: [UseTree], T!['}'] } |
@@ -594,21 +593,21 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
594 | qualifier: Path, | 593 | qualifier: Path, |
595 | } | 594 | } |
596 | struct PathSegment { | 595 | struct PathSegment { |
597 | Coloncolon, LAngle, NameRef, TypeArgList, ParamList, RetType, PathType, RAngle | 596 | T![::], T![<], NameRef, TypeArgList, ParamList, RetType, PathType, T![>] |
598 | } | 597 | } |
599 | struct TypeArgList { | 598 | struct TypeArgList { |
600 | Coloncolon, | 599 | T![::], |
601 | LAngle, | 600 | T![<], |
602 | generic_args: [GenericArg], | 601 | generic_args: [GenericArg], |
603 | type_args: [TypeArg], | 602 | type_args: [TypeArg], |
604 | lifetime_args: [LifetimeArg], | 603 | lifetime_args: [LifetimeArg], |
605 | assoc_type_args: [AssocTypeArg], | 604 | assoc_type_args: [AssocTypeArg], |
606 | const_args: [ConstArg], | 605 | const_args: [ConstArg], |
607 | RAngle | 606 | T![>] |
608 | } | 607 | } |
609 | struct TypeArg { TypeRef } | 608 | struct TypeArg { TypeRef } |
610 | struct AssocTypeArg : TypeBoundsOwner { NameRef, T![=], TypeRef } | 609 | struct AssocTypeArg : TypeBoundsOwner { NameRef, T![=], TypeRef } |
611 | struct LifetimeArg { Lifetime } | 610 | struct LifetimeArg { T![lifetime] } |
612 | struct ConstArg { Literal, T![=], BlockExpr } | 611 | struct ConstArg { Literal, T![=], BlockExpr } |
613 | 612 | ||
614 | struct MacroItems: ModuleItemOwner{ } | 613 | struct MacroItems: ModuleItemOwner{ } |
@@ -767,37 +766,4 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
767 | TupleFieldDefList, | 766 | TupleFieldDefList, |
768 | } | 767 | } |
769 | }, | 768 | }, |
770 | |||
771 | token_enums: &ast_enums! { | ||
772 | enum RangeSeparator { Dotdot, Dotdotdot, Dotdoteq} | ||
773 | |||
774 | enum PrefixOp { | ||
775 | Minus, | ||
776 | T![!], | ||
777 | Star | ||
778 | } | ||
779 | |||
780 | enum RangeOp { | ||
781 | Dotdot, | ||
782 | Dotdoteq | ||
783 | } | ||
784 | |||
785 | enum LiteralToken { | ||
786 | IntNumber, | ||
787 | FloatNumber, | ||
788 | String, | ||
789 | RawString, | ||
790 | // TrueKw, | ||
791 | // FalseKw, | ||
792 | ByteString, | ||
793 | RawByteString, | ||
794 | Char, | ||
795 | Byte | ||
796 | } | ||
797 | |||
798 | enum NameRefToken { | ||
799 | Ident, | ||
800 | IntNumber | ||
801 | } | ||
802 | }, | ||
803 | }; | 769 | }; |
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index 678b40133..e6ba2009c 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs | |||
@@ -24,7 +24,6 @@ const ERR_INLINE_TESTS_DIR: &str = "crates/ra_syntax/test_data/parser/inline/err | |||
24 | 24 | ||
25 | const SYNTAX_KINDS: &str = "crates/ra_parser/src/syntax_kind/generated.rs"; | 25 | const SYNTAX_KINDS: &str = "crates/ra_parser/src/syntax_kind/generated.rs"; |
26 | const AST_NODES: &str = "crates/ra_syntax/src/ast/generated/nodes.rs"; | 26 | const AST_NODES: &str = "crates/ra_syntax/src/ast/generated/nodes.rs"; |
27 | const AST_TOKENS: &str = "crates/ra_syntax/src/ast/generated/tokens.rs"; | ||
28 | 27 | ||
29 | const ASSISTS_DIR: &str = "crates/ra_assists/src/handlers"; | 28 | const ASSISTS_DIR: &str = "crates/ra_assists/src/handlers"; |
30 | const ASSISTS_TESTS: &str = "crates/ra_assists/src/doc_tests/generated.rs"; | 29 | const ASSISTS_TESTS: &str = "crates/ra_assists/src/doc_tests/generated.rs"; |
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs index 4c9e447a3..ce18f2b8f 100644 --- a/xtask/src/codegen/gen_syntax.rs +++ b/xtask/src/codegen/gen_syntax.rs | |||
@@ -3,10 +3,7 @@ | |||
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 | ||
6 | use std::{ | 6 | use std::collections::{BTreeSet, HashSet}; |
7 | borrow::Cow, | ||
8 | collections::{BTreeSet, HashSet}, | ||
9 | }; | ||
10 | 7 | ||
11 | use proc_macro2::{Punct, Spacing}; | 8 | use proc_macro2::{Punct, Spacing}; |
12 | use quote::{format_ident, quote}; | 9 | use quote::{format_ident, quote}; |
@@ -26,10 +23,6 @@ pub fn generate_syntax(mode: Mode) -> Result<()> { | |||
26 | let contents = generate_nodes(KINDS_SRC, AST_SRC)?; | 23 | let contents = generate_nodes(KINDS_SRC, AST_SRC)?; |
27 | update(ast_nodes_file.as_path(), &contents, mode)?; | 24 | update(ast_nodes_file.as_path(), &contents, mode)?; |
28 | 25 | ||
29 | let ast_tokens_file = project_root().join(codegen::AST_TOKENS); | ||
30 | let contents = generate_tokens(KINDS_SRC, AST_SRC)?; | ||
31 | update(ast_tokens_file.as_path(), &contents, mode)?; | ||
32 | |||
33 | Ok(()) | 26 | Ok(()) |
34 | } | 27 | } |
35 | 28 | ||
@@ -40,147 +33,7 @@ struct ElementKinds { | |||
40 | has_tokens: bool, | 33 | has_tokens: bool, |
41 | } | 34 | } |
42 | 35 | ||
43 | fn generate_tokens(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | ||
44 | let all_token_kinds: Vec<_> = kinds | ||
45 | .punct | ||
46 | .into_iter() | ||
47 | .map(|(_, kind)| kind) | ||
48 | .copied() | ||
49 | .map(|x| x.into()) | ||
50 | .chain( | ||
51 | kinds | ||
52 | .keywords | ||
53 | .into_iter() | ||
54 | .chain(kinds.contextual_keywords.into_iter()) | ||
55 | .map(|name| Cow::Owned(format!("{}_KW", to_upper_snake_case(&name)))), | ||
56 | ) | ||
57 | .chain(kinds.literals.into_iter().copied().map(|x| x.into())) | ||
58 | .chain(kinds.tokens.into_iter().copied().map(|x| x.into())) | ||
59 | .collect(); | ||
60 | |||
61 | let tokens = all_token_kinds.iter().filter_map(|kind_str| { | ||
62 | if kind_str.ends_with("_KW") { | ||
63 | return None; | ||
64 | } | ||
65 | let kind_str = &**kind_str; | ||
66 | let kind = format_ident!("{}", kind_str); | ||
67 | let name = format_ident!("{}", to_pascal_case(kind_str)); | ||
68 | let res = quote! { | ||
69 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
70 | pub struct #name { | ||
71 | pub(crate) syntax: SyntaxToken, | ||
72 | } | ||
73 | |||
74 | impl std::fmt::Display for #name { | ||
75 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
76 | std::fmt::Display::fmt(&self.syntax, f) | ||
77 | } | ||
78 | } | ||
79 | |||
80 | impl AstToken for #name { | ||
81 | fn can_cast(kind: SyntaxKind) -> bool { kind == #kind } | ||
82 | fn cast(syntax: SyntaxToken) -> Option<Self> { | ||
83 | if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } | ||
84 | } | ||
85 | fn syntax(&self) -> &SyntaxToken { &self.syntax } | ||
86 | } | ||
87 | }; | ||
88 | Some(res) | ||
89 | }); | ||
90 | |||
91 | let enums = grammar.token_enums.iter().map(|en| { | ||
92 | let variants = en.variants.iter().map(|var| format_ident!("{}", var)).collect::<Vec<_>>(); | ||
93 | let name = format_ident!("{}", en.name); | ||
94 | let kinds = variants | ||
95 | .iter() | ||
96 | .map(|name| format_ident!("{}", to_upper_snake_case(&name.to_string()))) | ||
97 | .collect::<Vec<_>>(); | ||
98 | assert!(en.traits.is_empty()); | ||
99 | |||
100 | quote! { | ||
101 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
102 | pub enum #name { | ||
103 | #(#variants(#variants),)* | ||
104 | } | ||
105 | |||
106 | #( | ||
107 | impl From<#variants> for #name { | ||
108 | fn from(node: #variants) -> #name { | ||
109 | #name::#variants(node) | ||
110 | } | ||
111 | } | ||
112 | )* | ||
113 | |||
114 | impl std::fmt::Display for #name { | ||
115 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
116 | std::fmt::Display::fmt(self.syntax(), f) | ||
117 | } | ||
118 | } | ||
119 | |||
120 | impl AstToken for #name { | ||
121 | fn can_cast(kind: SyntaxKind) -> bool { | ||
122 | match kind { | ||
123 | #(#kinds)|* => true, | ||
124 | _ => false, | ||
125 | } | ||
126 | } | ||
127 | fn cast(syntax: SyntaxToken) -> Option<Self> { | ||
128 | let res = match syntax.kind() { | ||
129 | #( | ||
130 | #kinds => #name::#variants(#variants { syntax }), | ||
131 | )* | ||
132 | _ => return None, | ||
133 | }; | ||
134 | Some(res) | ||
135 | } | ||
136 | fn syntax(&self) -> &SyntaxToken { | ||
137 | match self { | ||
138 | #( | ||
139 | #name::#variants(it) => &it.syntax, | ||
140 | )* | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | }); | ||
146 | |||
147 | crate::reformat(quote! { | ||
148 | use crate::{SyntaxToken, SyntaxKind::{self, *}, ast::AstToken}; | ||
149 | |||
150 | #(#tokens)* | ||
151 | #(#enums)* | ||
152 | }) | ||
153 | } | ||
154 | |||
155 | fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | 36 | fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { |
156 | let all_token_kinds: Vec<_> = kinds | ||
157 | .punct | ||
158 | .into_iter() | ||
159 | .map(|(_, kind)| kind) | ||
160 | .copied() | ||
161 | .map(|x| x.into()) | ||
162 | .chain( | ||
163 | kinds | ||
164 | .keywords | ||
165 | .into_iter() | ||
166 | .chain(kinds.contextual_keywords.into_iter()) | ||
167 | .map(|name| Cow::Owned(format!("{}_KW", to_upper_snake_case(&name)))), | ||
168 | ) | ||
169 | .chain(kinds.literals.into_iter().copied().map(|x| x.into())) | ||
170 | .chain(kinds.tokens.into_iter().copied().map(|x| x.into())) | ||
171 | .collect(); | ||
172 | |||
173 | let mut token_kinds = HashSet::new(); | ||
174 | for kind in &all_token_kinds { | ||
175 | let kind = &**kind; | ||
176 | let name = to_pascal_case(kind); | ||
177 | token_kinds.insert(name); | ||
178 | } | ||
179 | |||
180 | for en in grammar.token_enums { | ||
181 | token_kinds.insert(en.name.to_string()); | ||
182 | } | ||
183 | |||
184 | let nodes = grammar.nodes.iter().map(|node| { | 37 | let nodes = grammar.nodes.iter().map(|node| { |
185 | let name = format_ident!("{}", node.name); | 38 | let name = format_ident!("{}", node.name); |
186 | let kind = format_ident!("{}", to_upper_snake_case(&name.to_string())); | 39 | let kind = format_ident!("{}", to_upper_snake_case(&name.to_string())); |
@@ -207,19 +60,9 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
207 | } | 60 | } |
208 | } | 61 | } |
209 | } else { | 62 | } else { |
210 | let is_token = token_kinds.contains(&ty.to_string()); | 63 | quote! { |
211 | if is_token { | 64 | pub fn #method_name(&self) -> Option<#ty> { |
212 | let method_name = format_ident!("{}_token", method_name); | 65 | support::child(&self.syntax) |
213 | quote! { | ||
214 | pub fn #method_name(&self) -> Option<#ty> { | ||
215 | support::token(&self.syntax) | ||
216 | } | ||
217 | } | ||
218 | } else { | ||
219 | quote! { | ||
220 | pub fn #method_name(&self) -> Option<#ty> { | ||
221 | support::child(&self.syntax) | ||
222 | } | ||
223 | } | 66 | } |
224 | } | 67 | } |
225 | } | 68 | } |
@@ -338,8 +181,6 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
338 | T, | 181 | T, |
339 | }; | 182 | }; |
340 | 183 | ||
341 | use super::tokens::*; | ||
342 | |||
343 | #(#nodes)* | 184 | #(#nodes)* |
344 | #(#enums)* | 185 | #(#enums)* |
345 | #(#displays)* | 186 | #(#displays)* |
@@ -456,6 +297,8 @@ fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> Result<String> { | |||
456 | macro_rules! T { | 297 | macro_rules! T { |
457 | #((#punctuation_values) => { $crate::SyntaxKind::#punctuation };)* | 298 | #((#punctuation_values) => { $crate::SyntaxKind::#punctuation };)* |
458 | #((#all_keywords_idents) => { $crate::SyntaxKind::#all_keywords };)* | 299 | #((#all_keywords_idents) => { $crate::SyntaxKind::#all_keywords };)* |
300 | (lifetime) => { $crate::SyntaxKind::LIFETIME }; | ||
301 | (ident) => { $crate::SyntaxKind::IDENT }; | ||
459 | } | 302 | } |
460 | }; | 303 | }; |
461 | 304 | ||
@@ -535,8 +378,21 @@ impl Field<'_> { | |||
535 | "')'" => "r_paren", | 378 | "')'" => "r_paren", |
536 | "'['" => "l_brack", | 379 | "'['" => "l_brack", |
537 | "']'" => "r_brack", | 380 | "']'" => "r_brack", |
381 | "<" => "l_angle", | ||
382 | ">" => "r_angle", | ||
538 | "=" => "eq", | 383 | "=" => "eq", |
539 | "!" => "excl", | 384 | "!" => "excl", |
385 | "*" => "star", | ||
386 | "&" => "amp", | ||
387 | "_" => "underscore", | ||
388 | "." => "dot", | ||
389 | ".." => "dotdot", | ||
390 | "..." => "dotdotdot", | ||
391 | "=>" => "fat_arrow", | ||
392 | "@" => "at", | ||
393 | ":" => "colon", | ||
394 | "::" => "coloncolon", | ||
395 | "#" => "pound", | ||
540 | _ => name, | 396 | _ => name, |
541 | }; | 397 | }; |
542 | format_ident!("{}_token", name) | 398 | format_ident!("{}_token", name) |