aboutsummaryrefslogtreecommitdiff
path: root/xtask/src/codegen
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-04-09 09:47:05 +0100
committerAleksey Kladov <[email protected]>2020-04-09 10:04:18 +0100
commit8f01e62bb962fbe282344125f6ace54326efcaa3 (patch)
treee3982d1b2adace537e621ece4706603e657e18de /xtask/src/codegen
parent68196ccc10c60de52bb771d295879456f73ede95 (diff)
Scale back the traits
Diffstat (limited to 'xtask/src/codegen')
-rw-r--r--xtask/src/codegen/gen_syntax.rs168
1 files changed, 28 insertions, 140 deletions
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index c730c75ee..2dfb68371 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -97,11 +97,13 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
97 let name = format_ident!("{}", to_pascal_case(kind_str)); 97 let name = format_ident!("{}", to_pascal_case(kind_str));
98 quote! { 98 quote! {
99 #[derive(Debug, Clone, PartialEq, Eq, Hash)] 99 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
100 pub struct #name(SyntaxToken); 100 pub struct #name {
101 pub(crate) syntax: SyntaxToken,
102 }
101 103
102 impl std::fmt::Display for #name { 104 impl std::fmt::Display for #name {
103 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 105 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
104 std::fmt::Display::fmt(self.syntax(), f) 106 std::fmt::Display::fmt(&self.syntax, f)
105 } 107 }
106 } 108 }
107 109
@@ -112,29 +114,10 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
112 _ => false, 114 _ => false,
113 } 115 }
114 } 116 }
115 fn cast_or_return(syntax: SyntaxToken) -> Result<Self, SyntaxToken> { 117 fn cast(syntax: SyntaxToken) -> Option<Self> {
116 if Self::can_cast(syntax.kind()) { Ok(Self(syntax)) } else { Err(syntax) } 118 if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
117 }
118 fn syntax(&self) -> &SyntaxToken { &self.0 }
119 fn into_syntax(self) -> SyntaxToken { self.0 }
120 }
121
122 impl AstElement for #name {
123 fn can_cast_element(kind: SyntaxKind) -> bool {
124 match kind {
125 #kind => true,
126 _ => false,
127 }
128 }
129 fn cast_or_return_element(syntax: SyntaxElement) -> Result<Self, SyntaxElement> {
130 if Self::can_cast_element(syntax.kind()) { Ok(Self(syntax.into_token().unwrap())) } else { Err(syntax) }
131 }
132 fn syntax_element(&self) -> NodeOrToken<&SyntaxNode, &SyntaxToken> {
133 NodeOrToken::Token(&self.0)
134 }
135 fn into_syntax_element(self) -> SyntaxElement {
136 NodeOrToken::Token(self.0)
137 } 119 }
120 fn syntax(&self) -> &SyntaxToken { &self.syntax }
138 } 121 }
139 } 122 }
140 }); 123 });
@@ -156,28 +139,21 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
156 FieldSrc::Optional(ty) | FieldSrc::Many(ty) => ty, 139 FieldSrc::Optional(ty) | FieldSrc::Many(ty) => ty,
157 FieldSrc::Shorthand => name, 140 FieldSrc::Shorthand => name,
158 }; 141 };
159 let element_kinds = &element_kinds_map.get(*ty).unwrap_or_else(|| panic!("type not found: {}", *ty)); 142
160 let iter = if !element_kinds.has_tokens {
161 format_ident!("AstChildren")
162 } else if !element_kinds.has_nodes {
163 format_ident!("AstChildTokens")
164 } else {
165 format_ident!("AstChildElements")
166 };
167 let ty = format_ident!("{}", ty); 143 let ty = format_ident!("{}", ty);
168 144
169 match field { 145 match field {
170 FieldSrc::Many(_) => { 146 FieldSrc::Many(_) => {
171 quote! { 147 quote! {
172 pub fn #method_name(&self) -> #iter<#ty> { 148 pub fn #method_name(&self) -> AstChildren<#ty> {
173 #iter::new(&self.syntax) 149 AstChildren::new(&self.syntax)
174 } 150 }
175 } 151 }
176 } 152 }
177 FieldSrc::Optional(_) | FieldSrc::Shorthand => { 153 FieldSrc::Optional(_) | FieldSrc::Shorthand => {
178 quote! { 154 quote! {
179 pub fn #method_name(&self) -> Option<#ty> { 155 pub fn #method_name(&self) -> Option<#ty> {
180 #iter::new(&self.syntax).next() 156 AstChildren::new(&self.syntax).next()
181 } 157 }
182 } 158 }
183 } 159 }
@@ -203,29 +179,10 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
203 _ => false, 179 _ => false,
204 } 180 }
205 } 181 }
206 fn cast_or_return(syntax: SyntaxNode) -> Result<Self, SyntaxNode> { 182 fn cast(syntax: SyntaxNode) -> Option<Self> {
207 if Self::can_cast(syntax.kind()) { Ok(Self { syntax }) } else { Err(syntax) } 183 if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
208 } 184 }
209 fn syntax(&self) -> &SyntaxNode { &self.syntax } 185 fn syntax(&self) -> &SyntaxNode { &self.syntax }
210 fn into_syntax(self) -> SyntaxNode { self.syntax }
211 }
212
213 impl AstElement for #name {
214 fn can_cast_element(kind: SyntaxKind) -> bool {
215 match kind {
216 #kind => true,
217 _ => false,
218 }
219 }
220 fn cast_or_return_element(syntax: SyntaxElement) -> Result<Self, SyntaxElement> {
221 if Self::can_cast_element(syntax.kind()) { Ok(Self { syntax: syntax.into_node().unwrap() }) } else { Err(syntax) }
222 }
223 fn syntax_element(&self) -> NodeOrToken<&SyntaxNode, &SyntaxToken> {
224 NodeOrToken::Node(&self.syntax)
225 }
226 fn into_syntax_element(self) -> SyntaxElement {
227 NodeOrToken::Node(self.syntax)
228 }
229 } 186 }
230 187
231 #(#traits)* 188 #(#traits)*
@@ -238,71 +195,16 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
238 195
239 let enums = grammar.enums.iter().map(|en| { 196 let enums = grammar.enums.iter().map(|en| {
240 let variants = en.variants.iter().map(|var| format_ident!("{}", var)).collect::<Vec<_>>(); 197 let variants = en.variants.iter().map(|var| format_ident!("{}", var)).collect::<Vec<_>>();
241 let element_kinds = &element_kinds_map[&en.name.to_string()];
242 let name = format_ident!("{}", en.name); 198 let name = format_ident!("{}", en.name);
243 let kinds = en.variants 199 let kinds = variants
244 .iter() 200 .iter()
245 .map(|name| { 201 .map(|name| format_ident!("{}", to_upper_snake_case(&name.to_string())))
246 element_kinds_map[*name].kinds.iter().collect::<Vec<_>>()
247 })
248 .collect::<Vec<_>>(); 202 .collect::<Vec<_>>();
249 let traits = en.traits.iter().map(|trait_name| { 203 let traits = en.traits.iter().map(|trait_name| {
250 let trait_name = format_ident!("{}", trait_name); 204 let trait_name = format_ident!("{}", trait_name);
251 quote!(impl ast::#trait_name for #name {}) 205 quote!(impl ast::#trait_name for #name {})
252 }); 206 });
253 207
254 let all_kinds = &element_kinds.kinds;
255
256 let specific_ast_trait = if element_kinds.has_nodes != element_kinds.has_tokens {
257 let (ast_trait, syntax_type) = if element_kinds.has_tokens {
258 (
259 quote!(AstToken),
260 quote!(SyntaxToken),
261 )
262 } else {
263 (
264 quote!(AstNode),
265 quote!(SyntaxNode),
266 )
267 };
268
269 quote! {
270 impl #ast_trait for #name {
271 fn can_cast(kind: SyntaxKind) -> bool {
272 match kind {
273 #(#all_kinds)|* => true,
274 _ => false,
275 }
276 }
277 #[allow(unreachable_patterns)]
278 fn cast_or_return(syntax: #syntax_type) -> Result<Self, #syntax_type> {
279 match syntax.kind() {
280 #(
281 #(#kinds)|* => #variants::cast_or_return(syntax).map(|x| #name::#variants(x)),
282 )*
283 _ => Err(syntax),
284 }
285 }
286 fn syntax(&self) -> &#syntax_type {
287 match self {
288 #(
289 #name::#variants(it) => it.syntax(),
290 )*
291 }
292 }
293 fn into_syntax(self) -> #syntax_type {
294 match self {
295 #(
296 #name::#variants(it) => it.into_syntax(),
297 )*
298 }
299 }
300 }
301 }
302 } else {
303 Default::default()
304 };
305
306 quote! { 208 quote! {
307 #[derive(Debug, Clone, PartialEq, Eq, Hash)] 209 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
308 pub enum #name { 210 pub enum #name {
@@ -319,48 +221,34 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
319 221
320 impl std::fmt::Display for #name { 222 impl std::fmt::Display for #name {
321 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 223 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
322 match self { 224 std::fmt::Display::fmt(self.syntax(), f)
323 #(
324 #name::#variants(it) => std::fmt::Display::fmt(it, f),
325 )*
326 }
327 } 225 }
328 } 226 }
329 227
330 #specific_ast_trait 228 impl AstNode for #name {
331 229 fn can_cast(kind: SyntaxKind) -> bool {
332 impl AstElement for #name {
333 fn can_cast_element(kind: SyntaxKind) -> bool {
334 match kind { 230 match kind {
335 #(#all_kinds)|* => true, 231 #(#kinds)|* => true,
336 _ => false, 232 _ => false,
337 } 233 }
338 } 234 }
339 #[allow(unreachable_patterns)] 235 fn cast(syntax: SyntaxNode) -> Option<Self> {
340 fn cast_or_return_element(syntax: SyntaxElement) -> Result<Self, SyntaxElement> { 236 let res = match syntax.kind() {
341 match syntax.kind() {
342 #( 237 #(
343 #(#kinds)|* => #variants::cast_or_return_element(syntax).map(|x| #name::#variants(x)), 238 #kinds => #name::#variants(#variants { syntax }),
344 )* 239 )*
345 _ => Err(syntax), 240 _ => return None,
346 } 241 };
242 Some(res)
347 } 243 }
348 fn syntax_element(&self) -> NodeOrToken<&SyntaxNode, &SyntaxToken> { 244 fn syntax(&self) -> &SyntaxNode {
349 match self { 245 match self {
350 #( 246 #(
351 #name::#variants(it) => it.syntax_element(), 247 #name::#variants(it) => &it.syntax,
352 )*
353 }
354 }
355 fn into_syntax_element(self) -> SyntaxElement {
356 match self {
357 #(
358 #name::#variants(it) => it.into_syntax_element(),
359 )* 248 )*
360 } 249 }
361 } 250 }
362 } 251 }
363
364 #(#traits)* 252 #(#traits)*
365 } 253 }
366 }); 254 });
@@ -380,7 +268,7 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
380 #[allow(unused_imports)] 268 #[allow(unused_imports)]
381 use crate::{ 269 use crate::{
382 SyntaxNode, SyntaxToken, SyntaxElement, NodeOrToken, SyntaxKind::{self, *}, 270 SyntaxNode, SyntaxToken, SyntaxElement, NodeOrToken, SyntaxKind::{self, *},
383 ast::{self, AstNode, AstToken, AstElement, AstChildren, AstChildTokens, AstChildElements}, 271 ast::{self, AstNode, AstToken, AstChildren},
384 }; 272 };
385 273
386 #(#tokens)* 274 #(#tokens)*