diff options
Diffstat (limited to 'xtask/src/codegen')
-rw-r--r-- | xtask/src/codegen/gen_syntax.rs | 87 |
1 files changed, 58 insertions, 29 deletions
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)* |