diff options
Diffstat (limited to 'crates/ra_tools/src')
-rw-r--r-- | crates/ra_tools/src/boilerplate_gen.rs | 87 |
1 files changed, 50 insertions, 37 deletions
diff --git a/crates/ra_tools/src/boilerplate_gen.rs b/crates/ra_tools/src/boilerplate_gen.rs index 486a3fdec..01d092d48 100644 --- a/crates/ra_tools/src/boilerplate_gen.rs +++ b/crates/ra_tools/src/boilerplate_gen.rs | |||
@@ -37,41 +37,72 @@ fn generate_ast(grammar: &Grammar) -> Result<String> { | |||
37 | ast_node.variants.iter().map(|var| format_ident!("{}", var)).collect::<Vec<_>>(); | 37 | ast_node.variants.iter().map(|var| format_ident!("{}", var)).collect::<Vec<_>>(); |
38 | let name = format_ident!("{}", name); | 38 | let name = format_ident!("{}", name); |
39 | 39 | ||
40 | let kinds = if variants.is_empty() { vec![name.clone()] } else { variants.clone() } | 40 | let adt = if variants.is_empty() { |
41 | .into_iter() | 41 | let kind = format_ident!("{}", name.to_string().to_shouty_snake_case()); |
42 | .map(|name| format_ident!("{}", name.to_string().to_shouty_snake_case())) | 42 | quote! { |
43 | .collect::<Vec<_>>(); | 43 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
44 | pub struct #name { | ||
45 | pub(crate) syntax: SyntaxNode, | ||
46 | } | ||
44 | 47 | ||
45 | let variants = if variants.is_empty() { | 48 | impl AstNode for #name { |
46 | None | 49 | fn can_cast(kind: SyntaxKind) -> bool { |
50 | match kind { | ||
51 | #kind => true, | ||
52 | _ => false, | ||
53 | } | ||
54 | } | ||
55 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
56 | if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } | ||
57 | } | ||
58 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
59 | } | ||
60 | } | ||
47 | } else { | 61 | } else { |
48 | let kind_enum = format_ident!("{}Kind", name); | 62 | let kinds = variants |
49 | Some(quote!( | 63 | .iter() |
50 | pub enum #kind_enum { | 64 | .map(|name| format_ident!("{}", name.to_string().to_shouty_snake_case())) |
65 | .collect::<Vec<_>>(); | ||
66 | |||
67 | quote! { | ||
68 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
69 | pub enum #name { | ||
51 | #(#variants(#variants),)* | 70 | #(#variants(#variants),)* |
52 | } | 71 | } |
53 | 72 | ||
54 | #( | 73 | #( |
55 | impl From<#variants> for #name { | 74 | impl From<#variants> for #name { |
56 | fn from(node: #variants) -> #name { | 75 | fn from(node: #variants) -> #name { |
57 | #name { syntax: node.syntax } | 76 | #name::#variants(node) |
58 | } | 77 | } |
59 | } | 78 | } |
60 | )* | 79 | )* |
61 | 80 | ||
62 | impl #name { | 81 | impl AstNode for #name { |
63 | pub fn kind(&self) -> #kind_enum { | 82 | fn can_cast(kind: SyntaxKind) -> bool { |
64 | let syntax = self.syntax.clone(); | 83 | match kind { |
65 | match syntax.kind() { | 84 | #(#kinds)|* => true, |
85 | _ => false, | ||
86 | } | ||
87 | } | ||
88 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
89 | let res = match syntax.kind() { | ||
66 | #( | 90 | #( |
67 | #kinds => | 91 | #kinds => #name::#variants(#variants { syntax }), |
68 | #kind_enum::#variants(#variants { syntax }), | 92 | )* |
93 | _ => return None, | ||
94 | }; | ||
95 | Some(res) | ||
96 | } | ||
97 | fn syntax(&self) -> &SyntaxNode { | ||
98 | match self { | ||
99 | #( | ||
100 | #name::#variants(it) => &it.syntax, | ||
69 | )* | 101 | )* |
70 | _ => unreachable!(), | ||
71 | } | 102 | } |
72 | } | 103 | } |
73 | } | 104 | } |
74 | )) | 105 | } |
75 | }; | 106 | }; |
76 | 107 | ||
77 | let traits = ast_node.traits.iter().map(|trait_name| { | 108 | let traits = ast_node.traits.iter().map(|trait_name| { |
@@ -105,25 +136,7 @@ fn generate_ast(grammar: &Grammar) -> Result<String> { | |||
105 | }); | 136 | }); |
106 | 137 | ||
107 | quote! { | 138 | quote! { |
108 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 139 | #adt |
109 | pub struct #name { | ||
110 | pub(crate) syntax: SyntaxNode, | ||
111 | } | ||
112 | |||
113 | impl AstNode for #name { | ||
114 | fn can_cast(kind: SyntaxKind) -> bool { | ||
115 | match kind { | ||
116 | #(#kinds)|* => true, | ||
117 | _ => false, | ||
118 | } | ||
119 | } | ||
120 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
121 | if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } | ||
122 | } | ||
123 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
124 | } | ||
125 | |||
126 | #variants | ||
127 | 140 | ||
128 | #(#traits)* | 141 | #(#traits)* |
129 | 142 | ||