diff options
author | Aleksey Kladov <aleksey.kladov@gmail.com> | 2020-04-10 09:07:09 +0100 |
---|---|---|
committer | Aleksey Kladov <aleksey.kladov@gmail.com> | 2020-04-10 15:10:28 +0100 |
commit | f89f2e38855f5b47f68758e98139aa962cb7a01d (patch) | |
tree | 7065879c9b77c2843959abdf82356d75f36c500f /xtask/src/codegen | |
parent | ff5643c52445c516b8b32bc6062c66203ca13ee4 (diff) |
More readable ast_src for keywords
Diffstat (limited to 'xtask/src/codegen')
-rw-r--r-- | xtask/src/codegen/gen_syntax.rs | 90 |
1 files changed, 56 insertions, 34 deletions
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}; | |||
12 | use quote::{format_ident, quote}; | 12 | use quote::{format_ident, quote}; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | ast_src::{AstSrc, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC}, | 15 | ast_src::{AstSrc, Field, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC}, |
16 | codegen::{self, update, Mode}, | 16 | codegen::{self, update, Mode}, |
17 | project_root, Result, | 17 | project_root, Result, |
18 | }; | 18 | }; |
@@ -189,46 +189,30 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
189 | quote!(impl ast::#trait_name for #name {}) | 189 | quote!(impl ast::#trait_name for #name {}) |
190 | }); | 190 | }); |
191 | 191 | ||
192 | let methods = node.fields.iter().map(|(name, field)| { | 192 | let methods = node.fields.iter().map(|field| { |
193 | let is_kw = name.ends_with("Kw"); | 193 | let method_name = field.method_name(); |
194 | let method_name = match field { | 194 | let ty = field.ty(); |
195 | FieldSrc::Shorthand => { | ||
196 | let name = if is_kw { &name[..name.len() - 2] } else { &name }; | ||
197 | format_ident!("{}", to_lower_snake_case(name)) | ||
198 | } | ||
199 | _ => format_ident!("{}", name), | ||
200 | }; | ||
201 | let ty = match field { | ||
202 | FieldSrc::Optional(ty) | FieldSrc::Many(ty) => ty, | ||
203 | FieldSrc::Shorthand => name, | ||
204 | }; | ||
205 | |||
206 | let ty = format_ident!("{}", ty); | ||
207 | 195 | ||
208 | match field { | 196 | if field.is_many() { |
209 | FieldSrc::Many(_) => { | 197 | quote! { |
198 | pub fn #method_name(&self) -> AstChildren<#ty> { | ||
199 | support::children(&self.syntax) | ||
200 | } | ||
201 | } | ||
202 | } else { | ||
203 | if let Some(token_kind) = field.token_kind() { | ||
210 | quote! { | 204 | quote! { |
211 | pub fn #method_name(&self) -> AstChildren<#ty> { | 205 | pub fn #method_name(&self) -> Option<#ty> { |
212 | support::children(&self.syntax) | 206 | support::token2(&self.syntax, #token_kind) |
213 | } | 207 | } |
214 | } | 208 | } |
215 | } | 209 | } else { |
216 | FieldSrc::Optional(_) | FieldSrc::Shorthand => { | ||
217 | let is_token = token_kinds.contains(&ty.to_string()); | 210 | let is_token = token_kinds.contains(&ty.to_string()); |
218 | if is_token { | 211 | if is_token { |
219 | let method_name = format_ident!("{}_token", method_name); | 212 | let method_name = format_ident!("{}_token", method_name); |
220 | if is_kw { | 213 | quote! { |
221 | let token_kind = format_ident!("{}", to_upper_snake_case(name)); | 214 | pub fn #method_name(&self) -> Option<#ty> { |
222 | quote! { | 215 | support::token(&self.syntax) |
223 | pub fn #method_name(&self) -> Option<SyntaxToken> { | ||
224 | support::token2(&self.syntax, #token_kind) | ||
225 | } | ||
226 | } | ||
227 | } else { | ||
228 | quote! { | ||
229 | pub fn #method_name(&self) -> Option<#ty> { | ||
230 | support::token(&self.syntax) | ||
231 | } | ||
232 | } | 216 | } |
233 | } | 217 | } |
234 | } else { | 218 | } else { |
@@ -351,6 +335,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
351 | use crate::{ | 335 | use crate::{ |
352 | SyntaxNode, SyntaxToken, SyntaxKind::{self, *}, | 336 | SyntaxNode, SyntaxToken, SyntaxKind::{self, *}, |
353 | ast::{self, AstNode, AstChildren, support}, | 337 | ast::{self, AstNode, AstChildren, support}, |
338 | T, | ||
354 | }; | 339 | }; |
355 | 340 | ||
356 | use super::tokens::*; | 341 | use super::tokens::*; |
@@ -519,3 +504,40 @@ fn to_pascal_case(s: &str) -> String { | |||
519 | } | 504 | } |
520 | buf | 505 | buf |
521 | } | 506 | } |
507 | |||
508 | impl Field<'_> { | ||
509 | fn is_many(&self) -> bool { | ||
510 | match self { | ||
511 | Field::Node { src: FieldSrc::Many(_), .. } => true, | ||
512 | _ => false, | ||
513 | } | ||
514 | } | ||
515 | fn token_kind(&self) -> Option<proc_macro2::TokenStream> { | ||
516 | let res = match self { | ||
517 | Field::Token(token) => { | ||
518 | let token = format_ident!("{}", token); | ||
519 | quote! { T![#token] } | ||
520 | } | ||
521 | _ => return None, | ||
522 | }; | ||
523 | Some(res) | ||
524 | } | ||
525 | fn method_name(&self) -> proc_macro2::Ident { | ||
526 | match self { | ||
527 | Field::Token(name) => format_ident!("{}_token", name), | ||
528 | Field::Node { name, src } => match src { | ||
529 | FieldSrc::Shorthand => format_ident!("{}", to_lower_snake_case(name)), | ||
530 | _ => format_ident!("{}", name), | ||
531 | }, | ||
532 | } | ||
533 | } | ||
534 | fn ty(&self) -> proc_macro2::Ident { | ||
535 | match self { | ||
536 | Field::Token(_) => format_ident!("SyntaxToken"), | ||
537 | Field::Node { name, src } => match src { | ||
538 | FieldSrc::Optional(ty) | FieldSrc::Many(ty) => format_ident!("{}", ty), | ||
539 | FieldSrc::Shorthand => format_ident!("{}", name), | ||
540 | }, | ||
541 | } | ||
542 | } | ||
543 | } | ||