aboutsummaryrefslogtreecommitdiff
path: root/xtask/src/codegen
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-04-10 09:07:09 +0100
committerAleksey Kladov <[email protected]>2020-04-10 15:10:28 +0100
commitf89f2e38855f5b47f68758e98139aa962cb7a01d (patch)
tree7065879c9b77c2843959abdf82356d75f36c500f /xtask/src/codegen
parentff5643c52445c516b8b32bc6062c66203ca13ee4 (diff)
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 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};
12use quote::{format_ident, quote}; 12use quote::{format_ident, quote};
13 13
14use crate::{ 14use 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
508impl 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}