aboutsummaryrefslogtreecommitdiff
path: root/xtask/src/codegen/gen_syntax.rs
diff options
context:
space:
mode:
Diffstat (limited to 'xtask/src/codegen/gen_syntax.rs')
-rw-r--r--xtask/src/codegen/gen_syntax.rs87
1 files changed, 57 insertions, 30 deletions
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index 45b788bdb..cafad8070 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -10,7 +10,7 @@ use std::{
10 10
11use proc_macro2::{Punct, Spacing}; 11use proc_macro2::{Punct, Spacing};
12use quote::{format_ident, quote}; 12use quote::{format_ident, quote};
13use ungrammar::{Grammar, Rule}; 13use ungrammar::{rust_grammar, Grammar, Rule};
14 14
15use crate::{ 15use crate::{
16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC}, 16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC},
@@ -19,9 +19,7 @@ use crate::{
19}; 19};
20 20
21pub fn generate_syntax(mode: Mode) -> Result<()> { 21pub fn generate_syntax(mode: Mode) -> Result<()> {
22 let grammar = include_str!("rust.ungram") 22 let grammar = rust_grammar();
23 .parse::<Grammar>()
24 .unwrap_or_else(|err| panic!("\n \x1b[91merror\x1b[0m: {}\n", err));
25 let ast = lower(&grammar); 23 let ast = lower(&grammar);
26 24
27 let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS); 25 let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS);
@@ -153,25 +151,10 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> Result<String> {
153 quote!(impl ast::#trait_name for #name {}) 151 quote!(impl ast::#trait_name for #name {})
154 }); 152 });
155 153
156 ( 154 let ast_node = if en.name == "Stmt" {
155 quote! {}
156 } else {
157 quote! { 157 quote! {
158 #[pretty_doc_comment_placeholder_workaround]
159 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
160 pub enum #name {
161 #(#variants(#variants),)*
162 }
163
164 #(#traits)*
165 },
166 quote! {
167 #(
168 impl From<#variants> for #name {
169 fn from(node: #variants) -> #name {
170 #name::#variants(node)
171 }
172 }
173 )*
174
175 impl AstNode for #name { 158 impl AstNode for #name {
176 fn can_cast(kind: SyntaxKind) -> bool { 159 fn can_cast(kind: SyntaxKind) -> bool {
177 match kind { 160 match kind {
@@ -196,6 +179,28 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> Result<String> {
196 } 179 }
197 } 180 }
198 } 181 }
182 }
183 };
184
185 (
186 quote! {
187 #[pretty_doc_comment_placeholder_workaround]
188 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
189 pub enum #name {
190 #(#variants(#variants),)*
191 }
192
193 #(#traits)*
194 },
195 quote! {
196 #(
197 impl From<#variants> for #name {
198 fn from(node: #variants) -> #name {
199 #name::#variants(node)
200 }
201 }
202 )*
203 #ast_node
199 }, 204 },
200 ) 205 )
201 }) 206 })
@@ -476,7 +481,13 @@ impl Field {
476 }; 481 };
477 format_ident!("{}_token", name) 482 format_ident!("{}_token", name)
478 } 483 }
479 Field::Node { name, .. } => format_ident!("{}", name), 484 Field::Node { name, .. } => {
485 if name == "type" {
486 format_ident!("ty")
487 } else {
488 format_ident!("{}", name)
489 }
490 }
480 } 491 }
481 } 492 }
482 fn ty(&self) -> proc_macro2::Ident { 493 fn ty(&self) -> proc_macro2::Ident {
@@ -491,13 +502,7 @@ fn lower(grammar: &Grammar) -> AstSrc {
491 let mut res = AstSrc::default(); 502 let mut res = AstSrc::default();
492 res.tokens = vec!["Whitespace".into(), "Comment".into(), "String".into(), "RawString".into()]; 503 res.tokens = vec!["Whitespace".into(), "Comment".into(), "String".into(), "RawString".into()];
493 504
494 let nodes = grammar 505 let nodes = grammar.iter().collect::<Vec<_>>();
495 .iter()
496 .filter(|&node| match grammar[node].rule {
497 Rule::Node(it) if it == node => false,
498 _ => true,
499 })
500 .collect::<Vec<_>>();
501 506
502 for &node in &nodes { 507 for &node in &nodes {
503 let name = grammar[node].name.clone(); 508 let name = grammar[node].name.clone();
@@ -531,6 +536,7 @@ fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> {
531 for alternative in alternatives { 536 for alternative in alternatives {
532 match alternative { 537 match alternative {
533 Rule::Node(it) => variants.push(grammar[*it].name.clone()), 538 Rule::Node(it) => variants.push(grammar[*it].name.clone()),
539 Rule::Token(it) if grammar[*it].name == ";" => (),
534 _ => return None, 540 _ => return None,
535 } 541 }
536 } 542 }
@@ -572,6 +578,24 @@ fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, label: Option<&String>, r
572 } 578 }
573 Rule::Labeled { label: l, rule } => { 579 Rule::Labeled { label: l, rule } => {
574 assert!(label.is_none()); 580 assert!(label.is_none());
581 let manually_implemented = matches!(
582 l.as_str(),
583 "lhs"
584 | "rhs"
585 | "then_branch"
586 | "else_branch"
587 | "start"
588 | "end"
589 | "op"
590 | "index"
591 | "base"
592 | "value"
593 | "trait"
594 | "self_ty"
595 );
596 if manually_implemented {
597 return;
598 }
575 lower_rule(acc, grammar, Some(l), rule); 599 lower_rule(acc, grammar, Some(l), rule);
576 } 600 }
577 Rule::Seq(rules) | Rule::Alt(rules) => { 601 Rule::Seq(rules) | Rule::Alt(rules) => {
@@ -687,6 +711,9 @@ fn extract_struct_trait(node: &mut AstNodeSrc, trait_name: &str, methods: &[&str
687 711
688fn extract_enum_traits(ast: &mut AstSrc) { 712fn extract_enum_traits(ast: &mut AstSrc) {
689 for enm in &mut ast.enums { 713 for enm in &mut ast.enums {
714 if enm.name == "Stmt" {
715 continue;
716 }
690 let nodes = &ast.nodes; 717 let nodes = &ast.nodes;
691 let mut variant_traits = enm 718 let mut variant_traits = enm
692 .variants 719 .variants