From f89f2e38855f5b47f68758e98139aa962cb7a01d Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Fri, 10 Apr 2020 10:07:09 +0200
Subject: More readable ast_src for keywords

---
 crates/ra_syntax/src/ast/generated/nodes.rs | 146 ++++++++++++++-------------
 xtask/src/ast_src.rs                        | 147 +++++++++++++++-------------
 xtask/src/codegen/gen_syntax.rs             |  90 ++++++++++-------
 3 files changed, 210 insertions(+), 173 deletions(-)

diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs
index 20f663046..3b014e312 100644
--- a/crates/ra_syntax/src/ast/generated/nodes.rs
+++ b/crates/ra_syntax/src/ast/generated/nodes.rs
@@ -4,7 +4,7 @@ use super::tokens::*;
 use crate::{
     ast::{self, support, AstChildren, AstNode},
     SyntaxKind::{self, *},
-    SyntaxNode, SyntaxToken,
+    SyntaxNode, SyntaxToken, T,
 };
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct SourceFile {
@@ -48,11 +48,13 @@ impl ast::DocCommentsOwner for FnDef {}
 impl ast::AttrsOwner for FnDef {}
 impl FnDef {
     pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
-    pub fn const_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, CONST_KW) }
-    pub fn default_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, DEFAULT_KW) }
-    pub fn async_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, ASYNC_KW) }
-    pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, UNSAFE_KW) }
-    pub fn fn_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, FN_KW) }
+    pub fn const_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![const]) }
+    pub fn default_token(&self) -> Option<SyntaxToken> {
+        support::token2(&self.syntax, T![default])
+    }
+    pub fn async_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![async]) }
+    pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![unsafe]) }
+    pub fn fn_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![fn]) }
     pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
     pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
     pub fn body(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
@@ -98,7 +100,7 @@ impl ast::TypeParamsOwner for StructDef {}
 impl ast::AttrsOwner for StructDef {}
 impl ast::DocCommentsOwner for StructDef {}
 impl StructDef {
-    pub fn struct_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, STRUCT_KW) }
+    pub fn struct_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![struct]) }
     pub fn field_def_list(&self) -> Option<FieldDefList> { support::child(&self.syntax) }
     pub fn semi_token(&self) -> Option<Semi> { support::token(&self.syntax) }
 }
@@ -123,7 +125,7 @@ impl ast::TypeParamsOwner for UnionDef {}
 impl ast::AttrsOwner for UnionDef {}
 impl ast::DocCommentsOwner for UnionDef {}
 impl UnionDef {
-    pub fn union_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, UNION_KW) }
+    pub fn union_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![union]) }
     pub fn record_field_def_list(&self) -> Option<RecordFieldDefList> {
         support::child(&self.syntax)
     }
@@ -230,7 +232,7 @@ impl ast::TypeParamsOwner for EnumDef {}
 impl ast::AttrsOwner for EnumDef {}
 impl ast::DocCommentsOwner for EnumDef {}
 impl EnumDef {
-    pub fn enum_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, ENUM_KW) }
+    pub fn enum_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![enum]) }
     pub fn variant_list(&self) -> Option<EnumVariantList> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -299,9 +301,9 @@ impl ast::DocCommentsOwner for TraitDef {}
 impl ast::TypeParamsOwner for TraitDef {}
 impl ast::TypeBoundsOwner for TraitDef {}
 impl TraitDef {
-    pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, UNSAFE_KW) }
-    pub fn auto_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, AUTO_KW) }
-    pub fn trait_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, TRAIT_KW) }
+    pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![unsafe]) }
+    pub fn auto_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![auto]) }
+    pub fn trait_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![trait]) }
     pub fn item_list(&self) -> Option<ItemList> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -324,7 +326,7 @@ impl ast::NameOwner for Module {}
 impl ast::AttrsOwner for Module {}
 impl ast::DocCommentsOwner for Module {}
 impl Module {
-    pub fn mod_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, MOD_KW) }
+    pub fn mod_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![mod]) }
     pub fn item_list(&self) -> Option<ItemList> { support::child(&self.syntax) }
     pub fn semi_token(&self) -> Option<Semi> { support::token(&self.syntax) }
 }
@@ -371,8 +373,10 @@ impl ast::AttrsOwner for ConstDef {}
 impl ast::DocCommentsOwner for ConstDef {}
 impl ast::TypeAscriptionOwner for ConstDef {}
 impl ConstDef {
-    pub fn default_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, DEFAULT_KW) }
-    pub fn const_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, CONST_KW) }
+    pub fn default_token(&self) -> Option<SyntaxToken> {
+        support::token2(&self.syntax, T![default])
+    }
+    pub fn const_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![const]) }
     pub fn eq_token(&self) -> Option<Eq> { support::token(&self.syntax) }
     pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn semi_token(&self) -> Option<Semi> { support::token(&self.syntax) }
@@ -399,8 +403,8 @@ impl ast::AttrsOwner for StaticDef {}
 impl ast::DocCommentsOwner for StaticDef {}
 impl ast::TypeAscriptionOwner for StaticDef {}
 impl StaticDef {
-    pub fn static_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, STATIC_KW) }
-    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, MUT_KW) }
+    pub fn static_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![static]) }
+    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![mut]) }
     pub fn eq_token(&self) -> Option<Eq> { support::token(&self.syntax) }
     pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn semi_token(&self) -> Option<Semi> { support::token(&self.syntax) }
@@ -427,8 +431,10 @@ impl ast::AttrsOwner for TypeAliasDef {}
 impl ast::DocCommentsOwner for TypeAliasDef {}
 impl ast::TypeBoundsOwner for TypeAliasDef {}
 impl TypeAliasDef {
-    pub fn default_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, DEFAULT_KW) }
-    pub fn type_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, TYPE_KW) }
+    pub fn default_token(&self) -> Option<SyntaxToken> {
+        support::token2(&self.syntax, T![default])
+    }
+    pub fn type_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![type]) }
     pub fn eq_token(&self) -> Option<Eq> { support::token(&self.syntax) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
     pub fn semi_token(&self) -> Option<Semi> { support::token(&self.syntax) }
@@ -451,12 +457,14 @@ impl AstNode for ImplDef {
 impl ast::TypeParamsOwner for ImplDef {}
 impl ast::AttrsOwner for ImplDef {}
 impl ImplDef {
-    pub fn default_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, DEFAULT_KW) }
-    pub fn const_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, CONST_KW) }
-    pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, UNSAFE_KW) }
-    pub fn impl_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, IMPL_KW) }
+    pub fn default_token(&self) -> Option<SyntaxToken> {
+        support::token2(&self.syntax, T![default])
+    }
+    pub fn const_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![const]) }
+    pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![unsafe]) }
+    pub fn impl_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![impl]) }
     pub fn excl_token(&self) -> Option<Excl> { support::token(&self.syntax) }
-    pub fn for_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, FOR_KW) }
+    pub fn for_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![for]) }
     pub fn item_list(&self) -> Option<ItemList> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -552,8 +560,8 @@ impl AstNode for PointerType {
 }
 impl PointerType {
     pub fn star_token(&self) -> Option<Star> { support::token(&self.syntax) }
-    pub fn const_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, CONST_KW) }
-    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, MUT_KW) }
+    pub fn const_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![const]) }
+    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![mut]) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -616,7 +624,7 @@ impl AstNode for ReferenceType {
 impl ReferenceType {
     pub fn amp_token(&self) -> Option<Amp> { support::token(&self.syntax) }
     pub fn lifetime_token(&self) -> Option<Lifetime> { support::token(&self.syntax) }
-    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, MUT_KW) }
+    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![mut]) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -654,8 +662,8 @@ impl AstNode for FnPointerType {
 }
 impl FnPointerType {
     pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
-    pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, UNSAFE_KW) }
-    pub fn fn_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, FN_KW) }
+    pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![unsafe]) }
+    pub fn fn_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![fn]) }
     pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
     pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
 }
@@ -675,7 +683,7 @@ impl AstNode for ForType {
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
 impl ForType {
-    pub fn for_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, FOR_KW) }
+    pub fn for_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![for]) }
     pub fn type_param_list(&self) -> Option<TypeParamList> { support::child(&self.syntax) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
@@ -696,7 +704,7 @@ impl AstNode for ImplTraitType {
 }
 impl ast::TypeBoundsOwner for ImplTraitType {}
 impl ImplTraitType {
-    pub fn impl_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, IMPL_KW) }
+    pub fn impl_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![impl]) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct DynTraitType {
@@ -715,7 +723,7 @@ impl AstNode for DynTraitType {
 }
 impl ast::TypeBoundsOwner for DynTraitType {}
 impl DynTraitType {
-    pub fn dyn_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, DYN_KW) }
+    pub fn dyn_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![dyn]) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TupleExpr {
@@ -816,9 +824,9 @@ impl AstNode for LambdaExpr {
 }
 impl ast::AttrsOwner for LambdaExpr {}
 impl LambdaExpr {
-    pub fn static_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, STATIC_KW) }
-    pub fn async_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, ASYNC_KW) }
-    pub fn move_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, MOVE_KW) }
+    pub fn static_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![static]) }
+    pub fn async_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![async]) }
+    pub fn move_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![move]) }
     pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
     pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
     pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
@@ -840,7 +848,7 @@ impl AstNode for IfExpr {
 }
 impl ast::AttrsOwner for IfExpr {}
 impl IfExpr {
-    pub fn if_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, IF_KW) }
+    pub fn if_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![if]) }
     pub fn condition(&self) -> Option<Condition> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -861,7 +869,7 @@ impl AstNode for LoopExpr {
 impl ast::AttrsOwner for LoopExpr {}
 impl ast::LoopBodyOwner for LoopExpr {}
 impl LoopExpr {
-    pub fn loop_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, LOOP_KW) }
+    pub fn loop_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![loop]) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TryBlockExpr {
@@ -880,7 +888,7 @@ impl AstNode for TryBlockExpr {
 }
 impl ast::AttrsOwner for TryBlockExpr {}
 impl TryBlockExpr {
-    pub fn try_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, TRY_KW) }
+    pub fn try_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![try]) }
     pub fn body(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -901,9 +909,9 @@ impl AstNode for ForExpr {
 impl ast::AttrsOwner for ForExpr {}
 impl ast::LoopBodyOwner for ForExpr {}
 impl ForExpr {
-    pub fn for_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, FOR_KW) }
+    pub fn for_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![for]) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
-    pub fn in_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, IN_KW) }
+    pub fn in_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![in]) }
     pub fn iterable(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -924,7 +932,7 @@ impl AstNode for WhileExpr {
 impl ast::AttrsOwner for WhileExpr {}
 impl ast::LoopBodyOwner for WhileExpr {}
 impl WhileExpr {
-    pub fn while_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, WHILE_KW) }
+    pub fn while_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![while]) }
     pub fn condition(&self) -> Option<Condition> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -945,7 +953,7 @@ impl AstNode for ContinueExpr {
 impl ast::AttrsOwner for ContinueExpr {}
 impl ContinueExpr {
     pub fn continue_token(&self) -> Option<SyntaxToken> {
-        support::token2(&self.syntax, CONTINUE_KW)
+        support::token2(&self.syntax, T![continue])
     }
     pub fn lifetime_token(&self) -> Option<Lifetime> { support::token(&self.syntax) }
 }
@@ -966,7 +974,7 @@ impl AstNode for BreakExpr {
 }
 impl ast::AttrsOwner for BreakExpr {}
 impl BreakExpr {
-    pub fn break_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, BREAK_KW) }
+    pub fn break_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![break]) }
     pub fn lifetime_token(&self) -> Option<Lifetime> { support::token(&self.syntax) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
@@ -1006,7 +1014,7 @@ impl AstNode for BlockExpr {
 impl ast::AttrsOwner for BlockExpr {}
 impl BlockExpr {
     pub fn label(&self) -> Option<Label> { support::child(&self.syntax) }
-    pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, UNSAFE_KW) }
+    pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![unsafe]) }
     pub fn block(&self) -> Option<Block> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1130,7 +1138,7 @@ impl ast::AttrsOwner for AwaitExpr {}
 impl AwaitExpr {
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn dot_token(&self) -> Option<Dot> { support::token(&self.syntax) }
-    pub fn await_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, AWAIT_KW) }
+    pub fn await_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![await]) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TryExpr {
@@ -1149,7 +1157,7 @@ impl AstNode for TryExpr {
 }
 impl ast::AttrsOwner for TryExpr {}
 impl TryExpr {
-    pub fn try_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, TRY_KW) }
+    pub fn try_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![try]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1170,7 +1178,7 @@ impl AstNode for CastExpr {
 impl ast::AttrsOwner for CastExpr {}
 impl CastExpr {
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
-    pub fn as_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, AS_KW) }
+    pub fn as_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![as]) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1191,8 +1199,8 @@ impl AstNode for RefExpr {
 impl ast::AttrsOwner for RefExpr {}
 impl RefExpr {
     pub fn amp_token(&self) -> Option<Amp> { support::token(&self.syntax) }
-    pub fn raw_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, RAW_KW) }
-    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, MUT_KW) }
+    pub fn raw_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![raw]) }
+    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![mut]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1232,7 +1240,7 @@ impl AstNode for BoxExpr {
 }
 impl ast::AttrsOwner for BoxExpr {}
 impl BoxExpr {
-    pub fn box_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, BOX_KW) }
+    pub fn box_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![box]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1308,7 +1316,7 @@ impl AstNode for MatchExpr {
 }
 impl ast::AttrsOwner for MatchExpr {}
 impl MatchExpr {
-    pub fn match_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, MATCH_KW) }
+    pub fn match_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![match]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn match_arm_list(&self) -> Option<MatchArmList> { support::child(&self.syntax) }
 }
@@ -1371,7 +1379,7 @@ impl AstNode for MatchGuard {
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
 impl MatchGuard {
-    pub fn if_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, IF_KW) }
+    pub fn if_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![if]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1491,7 +1499,7 @@ impl AstNode for RefPat {
 }
 impl RefPat {
     pub fn amp_token(&self) -> Option<Amp> { support::token(&self.syntax) }
-    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, MUT_KW) }
+    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![mut]) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1510,7 +1518,7 @@ impl AstNode for BoxPat {
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
 impl BoxPat {
-    pub fn box_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, BOX_KW) }
+    pub fn box_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![box]) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1531,8 +1539,8 @@ impl AstNode for BindPat {
 impl ast::AttrsOwner for BindPat {}
 impl ast::NameOwner for BindPat {}
 impl BindPat {
-    pub fn ref_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, REF_KW) }
-    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, MUT_KW) }
+    pub fn ref_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![ref]) }
+    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![mut]) }
     pub fn at_token(&self) -> Option<At> { support::token(&self.syntax) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
 }
@@ -1788,10 +1796,10 @@ impl AstNode for Visibility {
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
 impl Visibility {
-    pub fn pub_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, PUB_KW) }
-    pub fn super_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, SUPER_KW) }
-    pub fn self_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, SELF_KW) }
-    pub fn crate_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, CRATE_KW) }
+    pub fn pub_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![pub]) }
+    pub fn super_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![super]) }
+    pub fn self_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![self]) }
+    pub fn crate_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![crate]) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Name {
@@ -1996,7 +2004,7 @@ impl AstNode for TypeBound {
 }
 impl TypeBound {
     pub fn lifetime_token(&self) -> Option<Lifetime> { support::token(&self.syntax) }
-    pub fn const_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, CONST_KW) }
+    pub fn const_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![const]) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -2053,7 +2061,7 @@ impl AstNode for WhereClause {
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
 impl WhereClause {
-    pub fn where_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, WHERE_KW) }
+    pub fn where_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![where]) }
     pub fn predicates(&self) -> AstChildren<WherePred> { support::children(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -2112,7 +2120,7 @@ impl AstNode for LetStmt {
 impl ast::AttrsOwner for LetStmt {}
 impl ast::TypeAscriptionOwner for LetStmt {}
 impl LetStmt {
-    pub fn let_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, LET_KW) }
+    pub fn let_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![let]) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn eq_token(&self) -> Option<Eq> { support::token(&self.syntax) }
     pub fn initializer(&self) -> Option<Expr> { support::child(&self.syntax) }
@@ -2134,7 +2142,7 @@ impl AstNode for Condition {
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
 impl Condition {
-    pub fn let_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, LET_KW) }
+    pub fn let_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![let]) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn eq_token(&self) -> Option<Eq> { support::token(&self.syntax) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
@@ -2203,7 +2211,7 @@ impl ast::AttrsOwner for SelfParam {}
 impl SelfParam {
     pub fn amp_token(&self) -> Option<Amp> { support::token(&self.syntax) }
     pub fn lifetime_token(&self) -> Option<Lifetime> { support::token(&self.syntax) }
-    pub fn self_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, SELF_KW) }
+    pub fn self_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![self]) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Param {
@@ -2244,7 +2252,7 @@ impl AstNode for UseItem {
 impl ast::AttrsOwner for UseItem {}
 impl ast::VisibilityOwner for UseItem {}
 impl UseItem {
-    pub fn use_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, USE_KW) }
+    pub fn use_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![use]) }
     pub fn use_tree(&self) -> Option<UseTree> { support::child(&self.syntax) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -2285,7 +2293,7 @@ impl AstNode for Alias {
 }
 impl ast::NameOwner for Alias {}
 impl Alias {
-    pub fn as_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, AS_KW) }
+    pub fn as_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![as]) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct UseTreeList {
@@ -2325,8 +2333,8 @@ impl AstNode for ExternCrateItem {
 impl ast::AttrsOwner for ExternCrateItem {}
 impl ast::VisibilityOwner for ExternCrateItem {}
 impl ExternCrateItem {
-    pub fn extern_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, EXTERN_KW) }
-    pub fn crate_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, CRATE_KW) }
+    pub fn extern_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![extern]) }
+    pub fn crate_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T![crate]) }
     pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
     pub fn alias(&self) -> Option<Alias> { support::child(&self.syntax) }
 }
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 15bd8a2e4..3da280551 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -233,7 +233,12 @@ pub(crate) struct AstSrc<'a> {
 pub(crate) struct AstNodeSrc<'a> {
     pub(crate) name: &'a str,
     pub(crate) traits: &'a [&'a str],
-    pub(crate) fields: &'a [(&'a str, FieldSrc<'a>)],
+    pub(crate) fields: &'a [Field<'a>],
+}
+
+pub(crate) enum Field<'a> {
+    Token(&'a str),
+    Node { name: &'a str, src: FieldSrc<'a> },
 }
 
 pub(crate) enum FieldSrc<'a> {
@@ -251,31 +256,34 @@ pub(crate) struct AstEnumSrc<'a> {
 macro_rules! ast_nodes {
     ($(
         struct $name:ident$(: $($trait:ident),*)? {
-            $($field_name:ident $(: $ty:tt)?),*$(,)?
+            $($field_name:ident $(![$token:tt])? $(: $ty:tt)?),*$(,)?
         }
     )*) => {
         [$(
             AstNodeSrc {
                 name: stringify!($name),
                 traits: &[$($(stringify!($trait)),*)?],
-                fields: &[$(
-                    (stringify!($field_name), field_ty!($field_name $($ty)?))
-                ),*],
+                fields: &[
+                    $(field!($(T![$token])? $field_name $($ty)?)),*
+                ],
 
             }
         ),*]
     };
 }
 
-macro_rules! field_ty {
+macro_rules! field {
+    (T![$token:tt] T) => {
+        Field::Token(stringify!($token))
+    };
     ($field_name:ident) => {
-        FieldSrc::Shorthand
+        Field::Node { name: stringify!($field_name), src: FieldSrc::Shorthand }
     };
     ($field_name:ident [$ty:ident]) => {
-        FieldSrc::Many(stringify!($ty))
+        Field::Node { name: stringify!($field_name), src: FieldSrc::Many(stringify!($ty)) }
     };
     ($field_name:ident $ty:ident) => {
-        FieldSrc::Optional(stringify!($ty))
+        Field::Node { name: stringify!($field_name), src: FieldSrc::Optional(stringify!($ty)) }
     };
 }
 
@@ -290,7 +298,6 @@ macro_rules! ast_enums {
                 name: stringify!($name),
                 traits: &[$($(stringify!($trait)),*)?],
                 variants: &[$(stringify!($variant)),*],
-
             }
         ),*]
     };
@@ -304,11 +311,11 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
 
         struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner {
             Abi,
-            ConstKw,
-            DefaultKw,
-            AsyncKw,
-            UnsafeKw,
-            FnKw,
+            T![const],
+            T![default],
+            T![async],
+            T![unsafe],
+            T![fn],
             ParamList,
             RetType,
             body: BlockExpr,
@@ -318,13 +325,13 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
         struct RetType { ThinArrow, TypeRef }
 
         struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
-            StructKw,
+            T![struct],
             FieldDefList,
             Semi
         }
 
         struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
-            UnionKw,
+            T![union],
             RecordFieldDefList,
         }
 
@@ -337,7 +344,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
         }
 
         struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
-            EnumKw,
+            T![enum],
             variant_list: EnumVariantList,
         }
         struct EnumVariantList {
@@ -352,14 +359,14 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
         }
 
         struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner {
-            UnsafeKw,
-            AutoKw,
-            TraitKw,
+            T![unsafe],
+            T![auto],
+            T![trait],
             ItemList,
         }
 
         struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner {
-            ModKw,
+            T![mod],
             ItemList,
             Semi
         }
@@ -371,36 +378,36 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
         }
 
         struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
-            DefaultKw,
-            ConstKw,
+            T![default],
+            T![const],
             Eq,
             body: Expr,
             Semi
         }
 
         struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
-            StaticKw,
-            MutKw,
+            T![static],
+            T![mut],
             Eq,
             body: Expr,
             Semi
         }
 
         struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner {
-            DefaultKw,
-            TypeKw,
+            T![default],
+            T![type],
             Eq,
             TypeRef,
             Semi
         }
 
         struct ImplDef: TypeParamsOwner, AttrsOwner {
-            DefaultKw,
-            ConstKw,
-            UnsafeKw,
-            ImplKw,
+            T![default],
+            T![const],
+            T![unsafe],
+            T![impl],
             Excl,
-            ForKw,
+            T![for],
             ItemList,
         }
 
@@ -408,42 +415,42 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
         struct TupleType { LParen, fields: [TypeRef], RParen }
         struct NeverType { Excl }
         struct PathType { Path }
-        struct PointerType { Star, ConstKw, MutKw, TypeRef }
+        struct PointerType { Star, T![const], T![mut], TypeRef }
         struct ArrayType { LBrack, TypeRef, Semi, Expr, RBrack }
         struct SliceType { LBrack, TypeRef, RBrack }
-        struct ReferenceType { Amp, Lifetime, MutKw, TypeRef }
+        struct ReferenceType { Amp, Lifetime, T![mut], TypeRef }
         struct PlaceholderType { Underscore }
-        struct FnPointerType { Abi, UnsafeKw, FnKw, ParamList, RetType }
-        struct ForType { ForKw, TypeParamList, TypeRef }
-        struct ImplTraitType: TypeBoundsOwner { ImplKw }
-        struct DynTraitType: TypeBoundsOwner { DynKw }
+        struct FnPointerType { Abi, T![unsafe], T![fn], ParamList, RetType }
+        struct ForType { T![for], TypeParamList, TypeRef }
+        struct ImplTraitType: TypeBoundsOwner { T![impl] }
+        struct DynTraitType: TypeBoundsOwner { T![dyn] }
 
         struct TupleExpr: AttrsOwner { LParen, exprs: [Expr], RParen }
         struct ArrayExpr: AttrsOwner { LBrack, exprs: [Expr], Semi, RBrack }
         struct ParenExpr: AttrsOwner { LParen, Expr, RParen }
         struct PathExpr  { Path }
         struct LambdaExpr: AttrsOwner {
-            StaticKw,
-            AsyncKw,
-            MoveKw,
+            T![static],
+            T![async],
+            T![move],
             ParamList,
             RetType,
             body: Expr,
         }
-        struct IfExpr: AttrsOwner { IfKw, Condition }
-        struct LoopExpr: AttrsOwner, LoopBodyOwner { LoopKw }
-        struct TryBlockExpr: AttrsOwner { TryKw, body: BlockExpr }
+        struct IfExpr: AttrsOwner { T![if], Condition }
+        struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] }
+        struct TryBlockExpr: AttrsOwner { T![try], body: BlockExpr }
         struct ForExpr: AttrsOwner, LoopBodyOwner {
-            ForKw,
+            T![for],
             Pat,
-            InKw,
+            T![in],
             iterable: Expr,
         }
-        struct WhileExpr: AttrsOwner, LoopBodyOwner { WhileKw, Condition }
-        struct ContinueExpr: AttrsOwner { ContinueKw, Lifetime }
-        struct BreakExpr: AttrsOwner { BreakKw, Lifetime, Expr }
+        struct WhileExpr: AttrsOwner, LoopBodyOwner { T![while], Condition }
+        struct ContinueExpr: AttrsOwner { T![continue], Lifetime }
+        struct BreakExpr: AttrsOwner { T![break], Lifetime, Expr }
         struct Label { Lifetime }
-        struct BlockExpr: AttrsOwner { Label, UnsafeKw, Block  }
+        struct BlockExpr: AttrsOwner { Label, T![unsafe], Block  }
         struct ReturnExpr: AttrsOwner { Expr }
         struct CallExpr: ArgListOwner { Expr }
         struct MethodCallExpr: AttrsOwner, ArgListOwner {
@@ -451,17 +458,17 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
         }
         struct IndexExpr: AttrsOwner { LBrack, RBrack }
         struct FieldExpr: AttrsOwner { Expr, Dot, NameRef }
-        struct AwaitExpr: AttrsOwner { Expr, Dot, AwaitKw }
-        struct TryExpr: AttrsOwner { TryKw, Expr }
-        struct CastExpr: AttrsOwner { Expr, AsKw, TypeRef }
-        struct RefExpr: AttrsOwner { Amp, RawKw, MutKw, Expr }
+        struct AwaitExpr: AttrsOwner { Expr, Dot, T![await] }
+        struct TryExpr: AttrsOwner { T![try], Expr }
+        struct CastExpr: AttrsOwner { Expr, T![as], TypeRef }
+        struct RefExpr: AttrsOwner { Amp, T![raw], T![mut], Expr }
         struct PrefixExpr: AttrsOwner { PrefixOp, Expr }
-        struct BoxExpr: AttrsOwner { BoxKw, Expr }
+        struct BoxExpr: AttrsOwner { T![box], Expr }
         struct RangeExpr: AttrsOwner { RangeOp }
         struct BinExpr: AttrsOwner { BinOp }
         struct Literal { LiteralToken }
 
-        struct MatchExpr: AttrsOwner { MatchKw, Expr, MatchArmList }
+        struct MatchExpr: AttrsOwner { T![match], Expr, MatchArmList }
         struct MatchArmList: AttrsOwner { LCurly, arms: [MatchArm], RCurly }
         struct MatchArm: AttrsOwner {
             pat: Pat,
@@ -469,7 +476,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
             FatArrow,
             Expr,
         }
-        struct MatchGuard { IfKw, Expr }
+        struct MatchGuard { T![if], Expr }
 
         struct RecordLit { Path, RecordFieldList}
         struct RecordFieldList {
@@ -483,9 +490,9 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
 
         struct OrPat { pats: [Pat] }
         struct ParenPat { LParen, Pat, RParen }
-        struct RefPat { Amp, MutKw, Pat }
-        struct BoxPat { BoxKw, Pat }
-        struct BindPat: AttrsOwner, NameOwner { RefKw, MutKw, At, Pat }
+        struct RefPat { Amp, T![mut], Pat }
+        struct BoxPat { T![box], Pat }
+        struct BindPat: AttrsOwner, NameOwner { T![ref], T![mut], At, Pat }
         struct PlaceholderPat { Underscore }
         struct DotDotPat { Dotdot }
         struct PathPat { Path }
@@ -508,7 +515,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
         struct TupleStructPat { Path, LParen, args: [Pat], RParen }
         struct TuplePat { LParen, args: [Pat], RParen }
 
-        struct Visibility { PubKw, SuperKw, SelfKw, CrateKw }
+        struct Visibility { T![pub], T![super], T![self], T![crate] }
         struct Name { Ident }
         struct NameRef { NameRefToken }
 
@@ -534,20 +541,20 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
             default_val: Expr,
         }
         struct LifetimeParam: AttrsOwner { Lifetime}
-        struct TypeBound { Lifetime, /* Question,  */ ConstKw, /* Question,  */ TypeRef}
+        struct TypeBound { Lifetime, /* Question,  */ T![const], /* Question,  */ TypeRef}
         struct TypeBoundList { bounds: [TypeBound] }
         struct WherePred: TypeBoundsOwner { Lifetime, TypeRef }
-        struct WhereClause { WhereKw, predicates: [WherePred] }
+        struct WhereClause { T![where], predicates: [WherePred] }
         struct Abi { String }
         struct ExprStmt: AttrsOwner { Expr, Semi }
         struct LetStmt: AttrsOwner, TypeAscriptionOwner {
-            LetKw,
+            T![let],
             Pat,
             Eq,
             initializer: Expr,
             Semi,
         }
-        struct Condition { LetKw, Pat, Eq, Expr }
+        struct Condition { T![let], Pat, Eq, Expr }
         struct Block: AttrsOwner, ModuleItemOwner {
             LCurly,
             statements: [Stmt],
@@ -560,22 +567,22 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
             params: [Param],
             RParen
         }
-        struct SelfParam: TypeAscriptionOwner, AttrsOwner { Amp, Lifetime, SelfKw }
+        struct SelfParam: TypeAscriptionOwner, AttrsOwner { Amp, Lifetime, T![self] }
         struct Param: TypeAscriptionOwner, AttrsOwner {
             Pat,
             Dotdotdot
         }
         struct UseItem: AttrsOwner, VisibilityOwner {
-            UseKw,
+            T![use],
             UseTree,
         }
         struct UseTree {
             Path, Star, UseTreeList, Alias
         }
-        struct Alias: NameOwner { AsKw }
+        struct Alias: NameOwner { T![as] }
         struct UseTreeList { LCurly, use_trees: [UseTree], RCurly }
         struct ExternCrateItem: AttrsOwner, VisibilityOwner {
-            ExternKw, CrateKw, NameRef, Alias,
+            T![extern], T![crate], NameRef, Alias,
         }
         struct ArgList {
             LParen,
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index cc98802f6..c4fb29bbf 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -12,7 +12,7 @@ use proc_macro2::{Punct, Spacing};
 use quote::{format_ident, quote};
 
 use crate::{
-    ast_src::{AstSrc, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC},
+    ast_src::{AstSrc, Field, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC},
     codegen::{self, update, Mode},
     project_root, Result,
 };
@@ -189,46 +189,30 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
             quote!(impl ast::#trait_name for #name {})
         });
 
-        let methods = node.fields.iter().map(|(name, field)| {
-            let is_kw = name.ends_with("Kw");
-            let method_name = match field {
-                FieldSrc::Shorthand => {
-                    let name = if is_kw { &name[..name.len() - 2] } else { &name };
-                    format_ident!("{}", to_lower_snake_case(name))
-                }
-                _ => format_ident!("{}", name),
-            };
-            let ty = match field {
-                FieldSrc::Optional(ty) | FieldSrc::Many(ty) => ty,
-                FieldSrc::Shorthand => name,
-            };
-
-            let ty = format_ident!("{}", ty);
+        let methods = node.fields.iter().map(|field| {
+            let method_name = field.method_name();
+            let ty = field.ty();
 
-            match field {
-                FieldSrc::Many(_) => {
+            if field.is_many() {
+                quote! {
+                    pub fn #method_name(&self) -> AstChildren<#ty> {
+                        support::children(&self.syntax)
+                    }
+                }
+            } else {
+                if let Some(token_kind) = field.token_kind() {
                     quote! {
-                        pub fn #method_name(&self) -> AstChildren<#ty> {
-                            support::children(&self.syntax)
+                        pub fn #method_name(&self) -> Option<#ty> {
+                            support::token2(&self.syntax, #token_kind)
                         }
                     }
-                }
-                FieldSrc::Optional(_) | FieldSrc::Shorthand => {
+                } else {
                     let is_token = token_kinds.contains(&ty.to_string());
                     if is_token {
                         let method_name = format_ident!("{}_token", method_name);
-                        if is_kw {
-                            let token_kind = format_ident!("{}", to_upper_snake_case(name));
-                            quote! {
-                                pub fn #method_name(&self) -> Option<SyntaxToken> {
-                                    support::token2(&self.syntax, #token_kind)
-                                }
-                            }
-                        } else {
-                            quote! {
-                                pub fn #method_name(&self) -> Option<#ty> {
-                                    support::token(&self.syntax)
-                                }
+                        quote! {
+                            pub fn #method_name(&self) -> Option<#ty> {
+                                support::token(&self.syntax)
                             }
                         }
                     } else {
@@ -351,6 +335,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
         use crate::{
             SyntaxNode, SyntaxToken, SyntaxKind::{self, *},
             ast::{self, AstNode, AstChildren, support},
+            T,
         };
 
         use super::tokens::*;
@@ -519,3 +504,40 @@ fn to_pascal_case(s: &str) -> String {
     }
     buf
 }
+
+impl Field<'_> {
+    fn is_many(&self) -> bool {
+        match self {
+            Field::Node { src: FieldSrc::Many(_), .. } => true,
+            _ => false,
+        }
+    }
+    fn token_kind(&self) -> Option<proc_macro2::TokenStream> {
+        let res = match self {
+            Field::Token(token) => {
+                let token = format_ident!("{}", token);
+                quote! { T![#token] }
+            }
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn method_name(&self) -> proc_macro2::Ident {
+        match self {
+            Field::Token(name) => format_ident!("{}_token", name),
+            Field::Node { name, src } => match src {
+                FieldSrc::Shorthand => format_ident!("{}", to_lower_snake_case(name)),
+                _ => format_ident!("{}", name),
+            },
+        }
+    }
+    fn ty(&self) -> proc_macro2::Ident {
+        match self {
+            Field::Token(_) => format_ident!("SyntaxToken"),
+            Field::Node { name, src } => match src {
+                FieldSrc::Optional(ty) | FieldSrc::Many(ty) => format_ident!("{}", ty),
+                FieldSrc::Shorthand => format_ident!("{}", name),
+            },
+        }
+    }
+}
-- 
cgit v1.2.3