about summary refs log tree commit diff
path: root/xtask/src/codegen
diff options
context:
space:
mode:
authorAleksey Kladov <aleksey.kladov@gmail.com>2020-04-10 10:07:09 +0200
committerAleksey Kladov <aleksey.kladov@gmail.com>2020-04-10 16:10:28 +0200
commitf89f2e38855f5b47f68758e98139aa962cb7a01d (patch)
tree7065879c9b77c2843959abdf82356d75f36c500f /xtask/src/codegen
parentff5643c52445c516b8b32bc6062c66203ca13ee4 (diff)
downloadrust-f89f2e38855f5b47f68758e98139aa962cb7a01d.tar.gz
rust-f89f2e38855f5b47f68758e98139aa962cb7a01d.zip
More readable ast_src for keywords
Diffstat (limited to 'xtask/src/codegen')
-rw-r--r--xtask/src/codegen/gen_syntax.rs90
1 files changed, 56 insertions, 34 deletions
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index cc98802f613..c4fb29bbfa6 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),
+            },
+        }
+    }
+}