diff options
author | Aleksey Kladov <[email protected]> | 2020-07-29 10:48:32 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-07-29 11:04:22 +0100 |
commit | 627eddbc7e5eb13fc17c1c655ee1c3864c6dd4fe (patch) | |
tree | 2c0b87a578496194db0e423e8488f9f6d5a57d76 /xtask/src/codegen | |
parent | 04d2b7b256657f8e6816f8ed67aa5608bfe9e261 (diff) |
Owned AST IR
Diffstat (limited to 'xtask/src/codegen')
-rw-r--r-- | xtask/src/codegen/gen_syntax.rs | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs index 745a25862..5a18b3e2b 100644 --- a/xtask/src/codegen/gen_syntax.rs +++ b/xtask/src/codegen/gen_syntax.rs | |||
@@ -9,28 +9,29 @@ use proc_macro2::{Punct, Spacing}; | |||
9 | use quote::{format_ident, quote}; | 9 | use quote::{format_ident, quote}; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | ast_src::{AstSrc, Field, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC}, | 12 | ast_src::{rust_ast, AstSrc, Field, FieldSrc, KindsSrc, KINDS_SRC}, |
13 | codegen::{self, update, Mode}, | 13 | codegen::{self, update, Mode}, |
14 | project_root, Result, | 14 | project_root, Result, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | pub fn generate_syntax(mode: Mode) -> Result<()> { | 17 | pub fn generate_syntax(mode: Mode) -> Result<()> { |
18 | let ast = rust_ast(); | ||
18 | let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS); | 19 | let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS); |
19 | let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; | 20 | let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; |
20 | update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; | 21 | update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; |
21 | 22 | ||
22 | let ast_tokens_file = project_root().join(codegen::AST_TOKENS); | 23 | let ast_tokens_file = project_root().join(codegen::AST_TOKENS); |
23 | let contents = generate_tokens(AST_SRC)?; | 24 | let contents = generate_tokens(&ast)?; |
24 | update(ast_tokens_file.as_path(), &contents, mode)?; | 25 | update(ast_tokens_file.as_path(), &contents, mode)?; |
25 | 26 | ||
26 | let ast_nodes_file = project_root().join(codegen::AST_NODES); | 27 | let ast_nodes_file = project_root().join(codegen::AST_NODES); |
27 | let contents = generate_nodes(KINDS_SRC, AST_SRC)?; | 28 | let contents = generate_nodes(KINDS_SRC, &ast)?; |
28 | update(ast_nodes_file.as_path(), &contents, mode)?; | 29 | update(ast_nodes_file.as_path(), &contents, mode)?; |
29 | 30 | ||
30 | Ok(()) | 31 | Ok(()) |
31 | } | 32 | } |
32 | 33 | ||
33 | fn generate_tokens(grammar: AstSrc<'_>) -> Result<String> { | 34 | fn generate_tokens(grammar: &AstSrc) -> Result<String> { |
34 | let tokens = grammar.tokens.iter().map(|token| { | 35 | let tokens = grammar.tokens.iter().map(|token| { |
35 | let name = format_ident!("{}", token); | 36 | let name = format_ident!("{}", token); |
36 | let kind = format_ident!("{}", to_upper_snake_case(token)); | 37 | let kind = format_ident!("{}", to_upper_snake_case(token)); |
@@ -62,13 +63,13 @@ fn generate_tokens(grammar: AstSrc<'_>) -> Result<String> { | |||
62 | Ok(pretty) | 63 | Ok(pretty) |
63 | } | 64 | } |
64 | 65 | ||
65 | fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | 66 | fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> Result<String> { |
66 | let (node_defs, node_boilerplate_impls): (Vec<_>, Vec<_>) = grammar | 67 | let (node_defs, node_boilerplate_impls): (Vec<_>, Vec<_>) = grammar |
67 | .nodes | 68 | .nodes |
68 | .iter() | 69 | .iter() |
69 | .map(|node| { | 70 | .map(|node| { |
70 | let name = format_ident!("{}", node.name); | 71 | let name = format_ident!("{}", node.name); |
71 | let kind = format_ident!("{}", to_upper_snake_case(node.name)); | 72 | let kind = format_ident!("{}", to_upper_snake_case(&node.name)); |
72 | let traits = node.traits.iter().map(|trait_name| { | 73 | let traits = node.traits.iter().map(|trait_name| { |
73 | let trait_name = format_ident!("{}", trait_name); | 74 | let trait_name = format_ident!("{}", trait_name); |
74 | quote!(impl ast::#trait_name for #name {}) | 75 | quote!(impl ast::#trait_name for #name {}) |
@@ -192,8 +193,8 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
192 | }) | 193 | }) |
193 | .unzip(); | 194 | .unzip(); |
194 | 195 | ||
195 | let enum_names = grammar.enums.iter().map(|it| it.name); | 196 | let enum_names = grammar.enums.iter().map(|it| &it.name); |
196 | let node_names = grammar.nodes.iter().map(|it| it.name); | 197 | let node_names = grammar.nodes.iter().map(|it| &it.name); |
197 | 198 | ||
198 | let display_impls = | 199 | let display_impls = |
199 | enum_names.chain(node_names.clone()).map(|it| format_ident!("{}", it)).map(|name| { | 200 | enum_names.chain(node_names.clone()).map(|it| format_ident!("{}", it)).map(|name| { |
@@ -212,7 +213,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
212 | .nodes | 213 | .nodes |
213 | .iter() | 214 | .iter() |
214 | .map(|kind| to_pascal_case(kind)) | 215 | .map(|kind| to_pascal_case(kind)) |
215 | .filter(|name| !defined_nodes.contains(name.as_str())) | 216 | .filter(|name| !defined_nodes.iter().any(|&it| it == name)) |
216 | { | 217 | { |
217 | eprintln!("Warning: node {} not defined in ast source", node); | 218 | eprintln!("Warning: node {} not defined in ast source", node); |
218 | } | 219 | } |
@@ -236,12 +237,12 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
236 | let mut res = String::with_capacity(ast.len() * 2); | 237 | let mut res = String::with_capacity(ast.len() * 2); |
237 | 238 | ||
238 | let mut docs = | 239 | let mut docs = |
239 | grammar.nodes.iter().map(|it| it.doc).chain(grammar.enums.iter().map(|it| it.doc)); | 240 | grammar.nodes.iter().map(|it| &it.doc).chain(grammar.enums.iter().map(|it| &it.doc)); |
240 | 241 | ||
241 | for chunk in ast.split("# [ pretty_doc_comment_placeholder_workaround ]") { | 242 | for chunk in ast.split("# [ pretty_doc_comment_placeholder_workaround ]") { |
242 | res.push_str(chunk); | 243 | res.push_str(chunk); |
243 | if let Some(doc) = docs.next() { | 244 | if let Some(doc) = docs.next() { |
244 | write_doc_comment(doc, &mut res); | 245 | write_doc_comment(&doc, &mut res); |
245 | } | 246 | } |
246 | } | 247 | } |
247 | 248 | ||
@@ -249,7 +250,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
249 | Ok(pretty) | 250 | Ok(pretty) |
250 | } | 251 | } |
251 | 252 | ||
252 | fn write_doc_comment(contents: &[&str], dest: &mut String) { | 253 | fn write_doc_comment(contents: &[String], dest: &mut String) { |
253 | for line in contents { | 254 | for line in contents { |
254 | writeln!(dest, "///{}", line).unwrap(); | 255 | writeln!(dest, "///{}", line).unwrap(); |
255 | } | 256 | } |
@@ -413,7 +414,7 @@ fn to_pascal_case(s: &str) -> String { | |||
413 | buf | 414 | buf |
414 | } | 415 | } |
415 | 416 | ||
416 | impl Field<'_> { | 417 | impl Field { |
417 | fn is_many(&self) -> bool { | 418 | fn is_many(&self) -> bool { |
418 | matches!(self, Field::Node { src: FieldSrc::Many(_), .. }) | 419 | matches!(self, Field::Node { src: FieldSrc::Many(_), .. }) |
419 | } | 420 | } |
@@ -429,7 +430,7 @@ impl Field<'_> { | |||
429 | fn method_name(&self) -> proc_macro2::Ident { | 430 | fn method_name(&self) -> proc_macro2::Ident { |
430 | match self { | 431 | match self { |
431 | Field::Token(name) => { | 432 | Field::Token(name) => { |
432 | let name = match *name { | 433 | let name = match name.as_str() { |
433 | ";" => "semicolon", | 434 | ";" => "semicolon", |
434 | "->" => "thin_arrow", | 435 | "->" => "thin_arrow", |
435 | "'{'" => "l_curly", | 436 | "'{'" => "l_curly", |