diff options
Diffstat (limited to 'xtask')
-rw-r--r-- | xtask/src/ast_src.rs | 8 | ||||
-rw-r--r-- | xtask/src/codegen/gen_syntax.rs | 87 |
2 files changed, 58 insertions, 37 deletions
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs index 3200acc86..5fed777ac 100644 --- a/xtask/src/ast_src.rs +++ b/xtask/src/ast_src.rs | |||
@@ -549,7 +549,6 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
549 | struct Block: AttrsOwner, ModuleItemOwner { | 549 | struct Block: AttrsOwner, ModuleItemOwner { |
550 | LCurly, | 550 | LCurly, |
551 | statements: [Stmt], | 551 | statements: [Stmt], |
552 | statements_or_semi: [StmtOrSemi], | ||
553 | Expr, | 552 | Expr, |
554 | RCurly, | 553 | RCurly, |
555 | } | 554 | } |
@@ -749,12 +748,10 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
749 | 748 | ||
750 | enum AttrInput { Literal, TokenTree } | 749 | enum AttrInput { Literal, TokenTree } |
751 | enum Stmt { | 750 | enum Stmt { |
752 | ModuleItem, | ||
753 | LetStmt, | 751 | LetStmt, |
754 | ExprStmt, | 752 | ExprStmt, |
755 | // macro calls are parsed as expression statements */ | 753 | // macro calls are parsed as expression statements */ |
756 | } | 754 | } |
757 | enum StmtOrSemi {Stmt, Semi} | ||
758 | 755 | ||
759 | enum LeftDelimiter { LParen, LBrack, LCurly } | 756 | enum LeftDelimiter { LParen, LBrack, LCurly } |
760 | enum RightDelimiter { RParen, RBrack, RCurly } | 757 | enum RightDelimiter { RParen, RBrack, RCurly } |
@@ -825,10 +822,5 @@ pub(crate) const AST_SRC: AstSrc = AstSrc { | |||
825 | RecordFieldDefList, | 822 | RecordFieldDefList, |
826 | TupleFieldDefList, | 823 | TupleFieldDefList, |
827 | } | 824 | } |
828 | |||
829 | enum AttrOrComment { | ||
830 | Attr, | ||
831 | Comment | ||
832 | } | ||
833 | }, | 825 | }, |
834 | }; | 826 | }; |
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs index 2dfb68371..6dae93aa2 100644 --- a/xtask/src/codegen/gen_syntax.rs +++ b/xtask/src/codegen/gen_syntax.rs | |||
@@ -146,14 +146,23 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
146 | FieldSrc::Many(_) => { | 146 | FieldSrc::Many(_) => { |
147 | quote! { | 147 | quote! { |
148 | pub fn #method_name(&self) -> AstChildren<#ty> { | 148 | pub fn #method_name(&self) -> AstChildren<#ty> { |
149 | AstChildren::new(&self.syntax) | 149 | support::children(&self.syntax) |
150 | } | 150 | } |
151 | } | 151 | } |
152 | } | 152 | } |
153 | FieldSrc::Optional(_) | FieldSrc::Shorthand => { | 153 | FieldSrc::Optional(_) | FieldSrc::Shorthand => { |
154 | quote! { | 154 | let is_token = element_kinds_map[&ty.to_string()].has_tokens; |
155 | pub fn #method_name(&self) -> Option<#ty> { | 155 | if is_token { |
156 | AstChildren::new(&self.syntax).next() | 156 | quote! { |
157 | pub fn #method_name(&self) -> Option<#ty> { | ||
158 | support::token(&self.syntax) | ||
159 | } | ||
160 | } | ||
161 | } else { | ||
162 | quote! { | ||
163 | pub fn #method_name(&self) -> Option<#ty> { | ||
164 | support::child(&self.syntax) | ||
165 | } | ||
157 | } | 166 | } |
158 | } | 167 | } |
159 | } | 168 | } |
@@ -205,6 +214,48 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
205 | quote!(impl ast::#trait_name for #name {}) | 214 | quote!(impl ast::#trait_name for #name {}) |
206 | }); | 215 | }); |
207 | 216 | ||
217 | let element_kinds = &element_kinds_map[&en.name.to_string()]; | ||
218 | assert!( | ||
219 | element_kinds.has_nodes ^ element_kinds.has_tokens, | ||
220 | "{}: {:#?}", | ||
221 | name, | ||
222 | element_kinds | ||
223 | ); | ||
224 | let specific_ast_trait = { | ||
225 | let (ast_trait, syntax_type) = if element_kinds.has_tokens { | ||
226 | (quote!(AstToken), quote!(SyntaxToken)) | ||
227 | } else { | ||
228 | (quote!(AstNode), quote!(SyntaxNode)) | ||
229 | }; | ||
230 | |||
231 | quote! { | ||
232 | impl #ast_trait for #name { | ||
233 | fn can_cast(kind: SyntaxKind) -> bool { | ||
234 | match kind { | ||
235 | #(#kinds)|* => true, | ||
236 | _ => false, | ||
237 | } | ||
238 | } | ||
239 | fn cast(syntax: #syntax_type) -> Option<Self> { | ||
240 | let res = match syntax.kind() { | ||
241 | #( | ||
242 | #kinds => #name::#variants(#variants { syntax }), | ||
243 | )* | ||
244 | _ => return None, | ||
245 | }; | ||
246 | Some(res) | ||
247 | } | ||
248 | fn syntax(&self) -> &#syntax_type { | ||
249 | match self { | ||
250 | #( | ||
251 | #name::#variants(it) => &it.syntax, | ||
252 | )* | ||
253 | } | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | }; | ||
258 | |||
208 | quote! { | 259 | quote! { |
209 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 260 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
210 | pub enum #name { | 261 | pub enum #name { |
@@ -225,30 +276,8 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
225 | } | 276 | } |
226 | } | 277 | } |
227 | 278 | ||
228 | impl AstNode for #name { | 279 | #specific_ast_trait |
229 | fn can_cast(kind: SyntaxKind) -> bool { | 280 | |
230 | match kind { | ||
231 | #(#kinds)|* => true, | ||
232 | _ => false, | ||
233 | } | ||
234 | } | ||
235 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
236 | let res = match syntax.kind() { | ||
237 | #( | ||
238 | #kinds => #name::#variants(#variants { syntax }), | ||
239 | )* | ||
240 | _ => return None, | ||
241 | }; | ||
242 | Some(res) | ||
243 | } | ||
244 | fn syntax(&self) -> &SyntaxNode { | ||
245 | match self { | ||
246 | #( | ||
247 | #name::#variants(it) => &it.syntax, | ||
248 | )* | ||
249 | } | ||
250 | } | ||
251 | } | ||
252 | #(#traits)* | 281 | #(#traits)* |
253 | } | 282 | } |
254 | }); | 283 | }); |
@@ -268,7 +297,7 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { | |||
268 | #[allow(unused_imports)] | 297 | #[allow(unused_imports)] |
269 | use crate::{ | 298 | use crate::{ |
270 | SyntaxNode, SyntaxToken, SyntaxElement, NodeOrToken, SyntaxKind::{self, *}, | 299 | SyntaxNode, SyntaxToken, SyntaxElement, NodeOrToken, SyntaxKind::{self, *}, |
271 | ast::{self, AstNode, AstToken, AstChildren}, | 300 | ast::{self, AstNode, AstToken, AstChildren, support}, |
272 | }; | 301 | }; |
273 | 302 | ||
274 | #(#tokens)* | 303 | #(#tokens)* |