From 0b5d0a41fde1ae03bc6643dad3b904f579f716b5 Mon Sep 17 00:00:00 2001
From: Ekaterina Babshukova <ekaterina.babshukova@yandex.ru>
Date: Thu, 3 Oct 2019 03:00:47 +0300
Subject: replace a chain of `if let` by macro

---
 crates/ra_ide_api/src/name_kind.rs    | 116 +++++++++++++++------
 crates/ra_ide_api/src/search_scope.rs | 186 ----------------------------------
 2 files changed, 86 insertions(+), 216 deletions(-)
 delete mode 100644 crates/ra_ide_api/src/search_scope.rs

(limited to 'crates/ra_ide_api/src')

diff --git a/crates/ra_ide_api/src/name_kind.rs b/crates/ra_ide_api/src/name_kind.rs
index 64adb1784..0effeb8a1 100644
--- a/crates/ra_ide_api/src/name_kind.rs
+++ b/crates/ra_ide_api/src/name_kind.rs
@@ -102,36 +102,92 @@ pub(crate) fn classify_name(
     let parent = name.syntax().parent()?;
     let file_id = file_id.into();
 
-    if let Some(pat) = ast::BindPat::cast(parent.clone()) {
-        return Some(Pat(AstPtr::new(&pat)));
+    macro_rules! match_ast {
+        (match $node:ident {
+            $( ast::$ast:ident($it:ident) => $res:block, )*
+            _ => $catch_all:expr,
+        }) => {{
+            $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )*
+            { $catch_all }
+        }};
     }
-    if let Some(var) = ast::EnumVariant::cast(parent.clone()) {
-        let src = hir::Source { file_id, ast: var };
-        let var = hir::EnumVariant::from_source(db, src)?;
-        return Some(Def(var.into()));
-    }
-    if let Some(field) = ast::RecordFieldDef::cast(parent.clone()) {
-        let src = hir::Source { file_id, ast: hir::FieldSource::Named(field) };
-        let field = hir::StructField::from_source(db, src)?;
-        return Some(FieldAccess(field));
-    }
-    if let Some(field) = ast::TupleFieldDef::cast(parent.clone()) {
-        let src = hir::Source { file_id, ast: hir::FieldSource::Pos(field) };
-        let field = hir::StructField::from_source(db, src)?;
-        return Some(FieldAccess(field));
-    }
-    if let Some(_) = parent.parent().and_then(ast::ItemList::cast) {
-        let ast = ast::ImplItem::cast(parent.clone())?;
-        let src = hir::Source { file_id, ast };
-        let item = hir::AssocItem::from_source(db, src)?;
-        return Some(AssocItem(item));
-    }
-    if let Some(item) = ast::ModuleItem::cast(parent.clone()) {
-        let src = hir::Source { file_id, ast: item };
-        let def = hir::ModuleDef::from_source(db, src)?;
-        return Some(Def(def));
-    }
-    // FIXME: TYPE_PARAM, ALIAS, MACRO_CALL; Union
 
-    None
+    // FIXME: add ast::MacroCall(it)
+    match_ast! {
+        match parent {
+            ast::BindPat(it) => {
+                let pat = AstPtr::new(&it);
+                Some(Pat(pat))
+            },
+            ast::RecordFieldDef(it) => {
+                let src = hir::Source { file_id, ast: hir::FieldSource::Named(it) };
+                let field = hir::StructField::from_source(db, src)?;
+                Some(FieldAccess(field))
+            },
+            ast::FnDef(it) => {
+                if parent.parent().and_then(ast::ItemList::cast).is_some() {
+                    let src = hir::Source { file_id, ast: ast::ImplItem::from(it) };
+                    let item = hir::AssocItem::from_source(db, src)?;
+                    Some(AssocItem(item))
+                } else {
+                    let src = hir::Source { file_id, ast: it };
+                    let def = hir::Function::from_source(db, src)?;
+                    Some(Def(def.into()))
+                }
+            },
+            ast::ConstDef(it) => {
+                if parent.parent().and_then(ast::ItemList::cast).is_some() {
+                    let src = hir::Source { file_id, ast: ast::ImplItem::from(it) };
+                    let item = hir::AssocItem::from_source(db, src)?;
+                    Some(AssocItem(item))
+                } else {
+                    let src = hir::Source { file_id, ast: it };
+                    let def = hir::Const::from_source(db, src)?;
+                    Some(Def(def.into()))
+                }
+            },
+            ast::TypeAliasDef(it) => {
+                if parent.parent().and_then(ast::ItemList::cast).is_some() {
+                    let src = hir::Source { file_id, ast: ast::ImplItem::from(it) };
+                    let item = hir::AssocItem::from_source(db, src)?;
+                    Some(AssocItem(item))
+                } else {
+                    let src = hir::Source { file_id, ast: it };
+                    let def = hir::TypeAlias::from_source(db, src)?;
+                    Some(Def(def.into()))
+                }
+            },
+            ast::Module(it) => {
+                let src = hir::Source { file_id, ast: hir::ModuleSource::Module(it) };
+                let def = hir::Module::from_definition(db, src)?;
+                Some(Def(def.into()))
+            },
+            ast::StructDef(it) => {
+                let src = hir::Source { file_id, ast: it };
+                let def = hir::Struct::from_source(db, src)?;
+                Some(Def(def.into()))
+            },
+            ast::EnumDef(it) => {
+                let src = hir::Source { file_id, ast: it };
+                let def = hir::Enum::from_source(db, src)?;
+                Some(Def(def.into()))
+            },
+            ast::TraitDef(it) => {
+                let src = hir::Source { file_id, ast: it };
+                let def = hir::Trait::from_source(db, src)?;
+                Some(Def(def.into()))
+            },
+            ast::StaticDef(it) => {
+                let src = hir::Source { file_id, ast: it };
+                let def = hir::Static::from_source(db, src)?;
+                Some(Def(def.into()))
+            },
+            ast::EnumVariant(it) => {
+                let src = hir::Source { file_id, ast: it };
+                let def = hir::EnumVariant::from_source(db, src)?;
+                Some(Def(def.into()))
+            },
+            _ => None,
+        }
+    }
 }
diff --git a/crates/ra_ide_api/src/search_scope.rs b/crates/ra_ide_api/src/search_scope.rs
deleted file mode 100644
index ca1ac2b03..000000000
--- a/crates/ra_ide_api/src/search_scope.rs
+++ /dev/null
@@ -1,186 +0,0 @@
-pub enum SearchScope {
-    Function(hir::Function),
-    Module(hir::Module),
-    Crate(hir::Crate),
-    Crates(Vec<hir::Crate>),
-}
-
-pub struct SearchScope{ 
-    pub scope: Vec<SyntaxNode>
-}
-
-pub fn find_all_refs(db: &RootDatabase, decl: NameKind) -> Vec<ReferenceDescriptor> {
-    let (module, visibility) = match decl {
-        FieldAccess(field) => {
-            let parent = field.parent_def(db);
-            let module = parent.module(db);
-            let visibility = match parent {
-                VariantDef::Struct(s) => s.source(db).ast.visibility(),
-                VariantDef::EnumVariant(v) => v.parent_enum(db).source(db).ast.visibility(),
-            };
-            (module, visibility)
-        }
-        AssocItem(item) => {
-            let parent = item.parent_trait(db)?;
-            let module = parent.module(db);
-            let visibility = parent.source(db).ast.visibility();
-            (module, visibility)
-        }
-        Def(def) => {
-            let (module, visibility) = match def {
-                ModuleDef::Module(m) => (m, ),
-                ModuleDef::Function(f) => (f.module(db), f.source(db).ast.visibility()),
-                ModuleDef::Adt::Struct(s) => (s.module(db), s.source(db).ast.visibility()),
-                ModuleDef::Adt::Union(u) => (u.module(db), u.source(db).ast.visibility()),
-                ModuleDef::Adt::Enum(e) => (e.module(db), e.source(db).ast.visibility()),
-                ModuleDef::EnumVariant(v) => (v.module(db), v.source(db).ast.visibility()),
-                ModuleDef::Const(c) => (c.module(db), c.source(db).ast.visibility()),
-                ModuleDef::Static(s) => (s.module(db), s.source(db).ast.visibility()),
-                ModuleDef::Trait(t) => (t.module(db), t.source(db).ast.visibility()),
-                ModuleDef::TypeAlias(a) => (a.module(db), a.source(db).ast.visibility()),
-                ModuleDef::BuiltinType(_) => return vec![];
-            };
-            (module, visibility)
-        }
-        // FIXME: add missing kinds
-        _ => return vec![];
-    };
-    let scope = scope(db, module, visibility);
-}
-
-fn scope(db: &RootDatabase, module: hir::Module, item_vis: Option<ast::Visibility>) -> SearchScope {
-    if let Some(v) = item_vis {
-        let krate = module.krate(db)?;
-
-        if v.syntax().text() == "pub" {
-            SearchScope::Crate(krate)
-        }
-        if v.syntax().text() == "pub(crate)" {
-            let crate_graph = db.crate_graph();
-            let crates = crate_graph.iter().filter(|id| {
-                crate_graph.dependencies(id).any(|d| d.crate_id() == krate.crate_id())
-            }).map(|id| Crate { id }).collect::<Vec<_>>();
-            crates.insert(0, krate);
-            SearchScope::Crates(crates)
-        }
-        // FIXME: "pub(super)", "pub(in path)"
-        SearchScope::Module(module)
-    }
-    SearchScope::Module(module)
-}
-
-fn process_one(db, scope: SearchScope, pat) {
-    match scope {
-        SearchScope::Crate(krate) => {
-            let text = db.file_text(position.file_id).as_str();
-            let parse = SourceFile::parse(text);
-            for (offset, name) in text.match_indices(pat) {
-                if let Some() = find_node_at_offset<ast::NameRef>(parse, offset) {
-                    
-                }
-            }
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use crate::{
-        mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId,
-        ReferenceSearchResult,
-    };
-    use insta::assert_debug_snapshot;
-    use test_utils::assert_eq_text;
-
-    #[test]
-    fn test_find_all_refs_for_local() {
-        let code = r#"
-            fn main() {
-                let mut i = 1;
-                let j = 1;
-                i = i<|> + j;
-
-                {
-                    i = 0;
-                }
-
-                i = 5;
-            }
-        "#;
-
-        let refs = get_all_refs(code);
-        assert_eq!(refs.len(), 5);
-    }
-
-    #[test]
-    fn test_find_all_refs_for_param_inside() {
-        let code = r#"
-    fn foo(i : u32) -> u32 {
-        i<|>
-    }"#;
-
-        let refs = get_all_refs(code);
-        assert_eq!(refs.len(), 2);
-    }
-
-    #[test]
-    fn test_find_all_refs_for_fn_param() {
-        let code = r#"
-    fn foo(i<|> : u32) -> u32 {
-        i
-    }"#;
-
-        let refs = get_all_refs(code);
-        assert_eq!(refs.len(), 2);
-    }
-
-    #[test]
-    fn test_find_all_refs_field_name() {
-        let code = r#"
-            //- /lib.rs
-            struct Foo {
-                spam<|>: u32,
-            }
-        "#;
-
-        let refs = get_all_refs(code);
-        assert_eq!(refs.len(), 1);
-    }
-
-    #[test]
-    fn test_find_all_refs_methods() {
-        let code = r#"
-            //- /lib.rs
-            struct Foo;
-            impl Foo {
-                pub fn a() {
-                    self.b()
-                }
-                fn b(&self) {}
-            }
-        "#;
-
-        let refs = get_all_refs(code);
-        assert_eq!(refs.len(), 1);
-    }
-
-    #[test]
-    fn test_find_all_refs_pub_enum() {
-        let code = r#"
-            //- /lib.rs
-            pub enum Foo {
-                A,
-                B<|>,
-                C,
-            }
-        "#;
-
-        let refs = get_all_refs(code);
-        assert_eq!(refs.len(), 1);
-    }
-
-    fn get_all_refs(text: &str) -> ReferenceSearchResult {
-        let (analysis, position) = single_file_with_position(text);
-        analysis.find_all_refs(position).unwrap().unwrap()
-    }
-}
\ No newline at end of file
-- 
cgit v1.2.3