diff options
Diffstat (limited to 'xtask')
-rw-r--r-- | xtask/src/ast_src.rs | 2 | ||||
-rw-r--r-- | xtask/src/codegen.rs | 1 | ||||
-rw-r--r-- | xtask/src/codegen/gen_syntax.rs | 35 |
3 files changed, 38 insertions, 0 deletions
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs index 554afc76a..7a20d9991 100644 --- a/xtask/src/ast_src.rs +++ b/xtask/src/ast_src.rs | |||
@@ -225,6 +225,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc { | |||
225 | }; | 225 | }; |
226 | 226 | ||
227 | pub(crate) struct AstSrc<'a> { | 227 | pub(crate) struct AstSrc<'a> { |
228 | pub(crate) tokens: &'a [&'a str], | ||
228 | pub(crate) nodes: &'a [AstNodeSrc<'a>], | 229 | pub(crate) nodes: &'a [AstNodeSrc<'a>], |
229 | pub(crate) enums: &'a [AstEnumSrc<'a>], | 230 | pub(crate) enums: &'a [AstEnumSrc<'a>], |
230 | } | 231 | } |
@@ -303,6 +304,7 @@ macro_rules! ast_enums { | |||
303 | } | 304 | } |
304 | 305 | ||
305 | pub(crate) const AST_SRC: AstSrc = AstSrc { | 306 | pub(crate) const AST_SRC: AstSrc = AstSrc { |
307 | tokens: &["Whitespace", "Comment", "String", "RawString"], | ||
306 | nodes: &ast_nodes! { | 308 | nodes: &ast_nodes! { |
307 | struct SourceFile: ModuleItemOwner, AttrsOwner { | 309 | struct SourceFile: ModuleItemOwner, AttrsOwner { |
308 | modules: [Module], | 310 | modules: [Module], |
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index e6ba2009c..678b40133 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs | |||
@@ -24,6 +24,7 @@ const ERR_INLINE_TESTS_DIR: &str = "crates/ra_syntax/test_data/parser/inline/err | |||
24 | 24 | ||
25 | const SYNTAX_KINDS: &str = "crates/ra_parser/src/syntax_kind/generated.rs"; | 25 | const SYNTAX_KINDS: &str = "crates/ra_parser/src/syntax_kind/generated.rs"; |
26 | const AST_NODES: &str = "crates/ra_syntax/src/ast/generated/nodes.rs"; | 26 | const AST_NODES: &str = "crates/ra_syntax/src/ast/generated/nodes.rs"; |
27 | const AST_TOKENS: &str = "crates/ra_syntax/src/ast/generated/tokens.rs"; | ||
27 | 28 | ||
28 | const ASSISTS_DIR: &str = "crates/ra_assists/src/handlers"; | 29 | const ASSISTS_DIR: &str = "crates/ra_assists/src/handlers"; |
29 | const ASSISTS_TESTS: &str = "crates/ra_assists/src/doc_tests/generated.rs"; | 30 | const ASSISTS_TESTS: &str = "crates/ra_assists/src/doc_tests/generated.rs"; |
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs index ce18f2b8f..fa48853d2 100644 --- a/xtask/src/codegen/gen_syntax.rs +++ b/xtask/src/codegen/gen_syntax.rs | |||
@@ -19,6 +19,10 @@ pub fn generate_syntax(mode: Mode) -> Result<()> { | |||
19 | let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; | 19 | let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; |
20 | update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; | 20 | update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; |
21 | 21 | ||
22 | let ast_tokens_file = project_root().join(codegen::AST_TOKENS); | ||
23 | let contents = generate_tokens(KINDS_SRC, AST_SRC)?; | ||
24 | update(ast_tokens_file.as_path(), &contents, mode)?; | ||
25 | |||
22 | let ast_nodes_file = project_root().join(codegen::AST_NODES); | 26 | let ast_nodes_file = project_root().join(codegen::AST_NODES); |
23 | let contents = generate_nodes(KINDS_SRC, AST_SRC)?; | 27 | let contents = generate_nodes(KINDS_SRC, AST_SRC)?; |
24 | update(ast_nodes_file.as_path(), &contents, mode)?; | 28 | update(ast_nodes_file.as_path(), &contents, mode)?; |
@@ -33,6 +37,37 @@ struct ElementKinds { | |||
33 | has_tokens: bool, | 37 | has_tokens: bool, |
34 | } | 38 | } |
35 | 39 | ||
40 | fn generate_tokens(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | ||
41 | let tokens = grammar.tokens.iter().map(|token| { | ||
42 | let name = format_ident!("{}", token); | ||
43 | let kind = format_ident!("{}", to_upper_snake_case(token)); | ||
44 | quote! { | ||
45 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
46 | pub struct #name { | ||
47 | pub(crate) syntax: SyntaxToken, | ||
48 | } | ||
49 | impl std::fmt::Display for #name { | ||
50 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
51 | std::fmt::Display::fmt(&self.syntax, f) | ||
52 | } | ||
53 | } | ||
54 | impl AstToken for #name { | ||
55 | fn can_cast(kind: SyntaxKind) -> bool { kind == #kind } | ||
56 | fn cast(syntax: SyntaxToken) -> Option<Self> { | ||
57 | if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } | ||
58 | } | ||
59 | fn syntax(&self) -> &SyntaxToken { &self.syntax } | ||
60 | } | ||
61 | } | ||
62 | }); | ||
63 | |||
64 | let pretty = crate::reformat(quote! { | ||
65 | use crate::{SyntaxKind::{self, *}, SyntaxToken, ast::AstToken}; | ||
66 | #(#tokens)* | ||
67 | })?; | ||
68 | Ok(pretty) | ||
69 | } | ||
70 | |||
36 | fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | 71 | fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { |
37 | let nodes = grammar.nodes.iter().map(|node| { | 72 | let nodes = grammar.nodes.iter().map(|node| { |
38 | let name = format_ident!("{}", node.name); | 73 | let name = format_ident!("{}", node.name); |