From 39e444d70145cbf61ddfdd202572d9c6a7f2fd3c Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Mon, 19 Aug 2019 13:58:49 +0300
Subject: remove ast::*Kind enums

With the new owned trees, we don't need an indirection here
---
 crates/ra_tools/src/boilerplate_gen.rs | 87 +++++++++++++++++++---------------
 1 file changed, 50 insertions(+), 37 deletions(-)

(limited to 'crates/ra_tools')

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> {
             ast_node.variants.iter().map(|var| format_ident!("{}", var)).collect::<Vec<_>>();
         let name = format_ident!("{}", name);
 
-        let kinds = if variants.is_empty() { vec![name.clone()] } else { variants.clone() }
-            .into_iter()
-            .map(|name| format_ident!("{}", name.to_string().to_shouty_snake_case()))
-            .collect::<Vec<_>>();
+        let adt = if variants.is_empty() {
+            let kind = format_ident!("{}", name.to_string().to_shouty_snake_case());
+            quote! {
+                #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+                pub struct #name {
+                    pub(crate) syntax: SyntaxNode,
+                }
 
-        let variants = if variants.is_empty() {
-            None
+                impl AstNode for #name {
+                    fn can_cast(kind: SyntaxKind) -> bool {
+                        match kind {
+                            #kind => true,
+                            _ => false,
+                        }
+                    }
+                    fn cast(syntax: SyntaxNode) -> Option<Self> {
+                        if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
+                    }
+                    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+                }
+            }
         } else {
-            let kind_enum = format_ident!("{}Kind", name);
-            Some(quote!(
-                pub enum #kind_enum {
+            let kinds = variants
+                .iter()
+                .map(|name| format_ident!("{}", name.to_string().to_shouty_snake_case()))
+                .collect::<Vec<_>>();
+
+            quote! {
+                #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+                pub enum #name {
                     #(#variants(#variants),)*
                 }
 
                 #(
                 impl From<#variants> for #name {
                     fn from(node: #variants) -> #name {
-                        #name { syntax: node.syntax }
+                        #name::#variants(node)
                     }
                 }
                 )*
 
-                impl #name {
-                    pub fn kind(&self) -> #kind_enum {
-                        let syntax = self.syntax.clone();
-                        match syntax.kind() {
+                impl AstNode for #name {
+                    fn can_cast(kind: SyntaxKind) -> bool {
+                        match kind {
+                            #(#kinds)|* => true,
+                            _ => false,
+                        }
+                    }
+                    fn cast(syntax: SyntaxNode) -> Option<Self> {
+                        let res = match syntax.kind() {
                             #(
-                            #kinds =>
-                                #kind_enum::#variants(#variants { syntax }),
+                            #kinds => #name::#variants(#variants { syntax }),
+                            )*
+                            _ => return None,
+                        };
+                        Some(res)
+                    }
+                    fn syntax(&self) -> &SyntaxNode {
+                        match self {
+                            #(
+                            #name::#variants(it) => &it.syntax,
                             )*
-                            _ => unreachable!(),
                         }
                     }
                 }
-            ))
+            }
         };
 
         let traits = ast_node.traits.iter().map(|trait_name| {
@@ -105,25 +136,7 @@ fn generate_ast(grammar: &Grammar) -> Result<String> {
         });
 
         quote! {
-            #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-            pub struct #name {
-                pub(crate) syntax: SyntaxNode,
-            }
-
-            impl AstNode for #name {
-                fn can_cast(kind: SyntaxKind) -> bool {
-                    match kind {
-                        #(#kinds)|* => true,
-                        _ => false,
-                    }
-                }
-                fn cast(syntax: SyntaxNode) -> Option<Self> {
-                    if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
-                }
-                fn syntax(&self) -> &SyntaxNode { &self.syntax }
-            }
-
-            #variants
+            #adt
 
             #(#traits)*
 
-- 
cgit v1.2.3