Repository: rust-analyzer/rust-analyzer
Pull request #2172 (2019-11-04 10:26:16)

Use new text DSL instead of crate_graph! macro


Patch:
diff --git a/crates/ra_assists/src/assists/early_return.rs b/crates/ra_assists/src/assists/early_return.rs
index 570a07a20c..ad6c5695a3 100644
--- a/crates/ra_assists/src/assists/early_return.rs
+++ b/crates/ra_assists/src/assists/early_return.rs
@@ -3,10 +3,9 @@ use std::ops::RangeInclusive;
 use hir::db::HirDatabase;
 use ra_syntax::{
     algo::replace_children,
-    ast::{self, edit::IndentLevel, make, Block, Pat::TupleStructPat},
+    ast::{self, edit::IndentLevel, make},
     AstNode,
     SyntaxKind::{FN_DEF, LOOP_EXPR, L_CURLY, R_CURLY, WHILE_EXPR, WHITESPACE},
-    SyntaxNode,
 };
 
 use crate::{
@@ -38,23 +37,7 @@ use crate::{
 // ```
 pub(crate) fn convert_to_guarded_return(ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
     let if_expr: ast::IfExpr = ctx.find_node_at_offset()?;
-    let cond = if_expr.condition()?;
-    let mut if_let_ident: Option<String> = None;
-
-    // Check if there is an IfLet that we can handle.
-    match cond.pat() {
-        None => {} // No IfLet, supported.
-        Some(TupleStructPat(ref pat)) if pat.args().count() == 1usize => match &pat.path() {
-            Some(p) => match p.qualifier() {
-                None => if_let_ident = Some(p.syntax().text().to_string()),
-                _ => return None,
-            },
-            _ => return None,
-        },
-        _ => return None, // Unsupported IfLet.
-    };
-
-    let expr = cond.expr()?;
+    let expr = if_expr.condition()?.expr()?;
     let then_block = if_expr.then_branch()?.block()?;
     if if_expr.else_branch().is_some() {
         return None;
@@ -80,8 +63,8 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx<impl HirDatabase>) -> Opt
     let parent_container = parent_block.syntax().parent()?.parent()?;
 
     let early_expression = match parent_container.kind() {
-        WHILE_EXPR | LOOP_EXPR => Some("continue"),
-        FN_DEF => Some("return"),
+        WHILE_EXPR | LOOP_EXPR => Some("continue;"),
+        FN_DEF => Some("return;"),
         _ => None,
     }?;
 
@@ -94,58 +77,34 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx<impl HirDatabase>) -> Opt
 
     ctx.add_assist(AssistId("convert_to_guarded_return"), "convert to guarded return", |edit| {
         let if_indent_level = IndentLevel::from_node(&if_expr.syntax());
-        let new_block = match if_let_ident {
-            None => {
-                // If.
-                let early_expression = &(early_expression.to_owned() + ";");
-                let new_expr =
-                    if_indent_level.increase_indent(make::if_expression(&expr, early_expression));
-                replace(new_expr, &then_block, &parent_block, &if_expr)
-            }
-            Some(if_let_ident) => {
-                // If-let.
-                let new_expr = if_indent_level.increase_indent(make::let_match_early(
-                    expr,
-                    &if_let_ident,
-                    early_expression,
-                ));
-                replace(new_expr, &then_block, &parent_block, &if_expr)
-            }
-        };
+        let new_if_expr =
+            if_indent_level.increase_indent(make::if_expression(&expr, early_expression));
+        let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone());
+        let end_of_then = then_block_items.syntax().last_child_or_token().unwrap();
+        let end_of_then =
+            if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) {
+                end_of_then.prev_sibling_or_token().unwrap()
+            } else {
+                end_of_then
+            };
+        let mut new_if_and_then_statements = new_if_expr.syntax().children_with_tokens().chain(
+            then_block_items
+                .syntax()
+                .children_with_tokens()
+                .skip(1)
+                .take_while(|i| *i != end_of_then),
+        );
+        let new_block = replace_children(
+            &parent_block.syntax(),
+            RangeInclusive::new(
+                if_expr.clone().syntax().clone().into(),
+                if_expr.syntax().clone().into(),
+            ),
+            &mut new_if_and_then_statements,
+        );
         edit.target(if_expr.syntax().text_range());
         edit.replace_ast(parent_block, ast::Block::cast(new_block).unwrap());
         edit.set_cursor(cursor_position);
-
-        fn replace(
-            new_expr: impl AstNode,
-            then_block: &Block,
-            parent_block: &Block,
-            if_expr: &ast::IfExpr,
-        ) -> SyntaxNode {
-            let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone());
-            let end_of_then = then_block_items.syntax().last_child_or_token().unwrap();
-            let end_of_then =
-                if end_of_then.prev_sibling_or_token().map(|n| n.kind()) == Some(WHITESPACE) {
-                    end_of_then.prev_sibling_or_token().unwrap()
-                } else {
-                    end_of_then
-                };
-            let mut then_statements = new_expr.syntax().children_with_tokens().chain(
-                then_block_items
-                    .syntax()
-                    .children_with_tokens()
-                    .skip(1)
-                    .take_while(|i| *i != end_of_then),
-            );
-            replace_children(
-                &parent_block.syntax(),
-                RangeInclusive::new(
-                    if_expr.clone().syntax().clone().into(),
-                    if_expr.syntax().clone().into(),
-                ),
-                &mut then_statements,
-            )
-        }
     })
 }
 
@@ -184,68 +143,6 @@ mod tests {
         );
     }
 
-    #[test]
-    fn convert_let_inside_fn() {
-        check_assist(
-            convert_to_guarded_return,
-            r#"
-            fn main(n: Option<String>) {
-                bar();
-                if<|> let Some(n) = n {
-                    foo(n);
-
-                    //comment
-                    bar();
-                }
-            }
-            "#,
-            r#"
-            fn main(n: Option<String>) {
-                bar();
-                le<|>t n = match n {
-                    Some(it) => it,
-                    None => return,
-                };
-                foo(n);
-
-                //comment
-                bar();
-            }
-            "#,
-        );
-    }
-
-    #[test]
-    fn convert_let_ok_inside_fn() {
-        check_assist(
-            convert_to_guarded_return,
-            r#"
-            fn main(n: Option<String>) {
-                bar();
-                if<|> let Ok(n) = n {
-                    foo(n);
-
-                    //comment
-                    bar();
-                }
-            }
-            "#,
-            r#"
-            fn main(n: Option<String>) {
-                bar();
-                le<|>t n = match n {
-                    Ok(it) => it,
-                    None => return,
-                };
-                foo(n);
-
-                //comment
-                bar();
-            }
-            "#,
-        );
-    }
-
     #[test]
     fn convert_inside_while() {
         check_assist(
@@ -274,35 +171,6 @@ mod tests {
         );
     }
 
-    #[test]
-    fn convert_let_inside_while() {
-        check_assist(
-            convert_to_guarded_return,
-            r#"
-            fn main() {
-                while true {
-                    if<|> let Some(n) = n {
-                        foo(n);
-                        bar();
-                    }
-                }
-            }
-            "#,
-            r#"
-            fn main() {
-                while true {
-                    le<|>t n = match n {
-                        Some(it) => it,
-                        None => continue,
-                    };
-                    foo(n);
-                    bar();
-                }
-            }
-            "#,
-        );
-    }
-
     #[test]
     fn convert_inside_loop() {
         check_assist(
@@ -331,35 +199,6 @@ mod tests {
         );
     }
 
-    #[test]
-    fn convert_let_inside_loop() {
-        check_assist(
-            convert_to_guarded_return,
-            r#"
-            fn main() {
-                loop {
-                    if<|> let Some(n) = n {
-                        foo(n);
-                        bar();
-                    }
-                }
-            }
-            "#,
-            r#"
-            fn main() {
-                loop {
-                    le<|>t n = match n {
-                        Some(it) => it,
-                        None => continue,
-                    };
-                    foo(n);
-                    bar();
-                }
-            }
-            "#,
-        );
-    }
-
     #[test]
     fn ignore_already_converted_if() {
         check_assist_not_applicable(
diff --git a/crates/ra_hir/src/marks.rs b/crates/ra_hir/src/marks.rs
index b423489a11..0d4fa5b673 100644
--- a/crates/ra_hir/src/marks.rs
+++ b/crates/ra_hir/src/marks.rs
@@ -1,21 +1,10 @@
 //! See test_utils/src/marks.rs
 
 test_utils::marks!(
-    bogus_paths
-    // FIXME: restore this mark once hir is split
-    name_res_works_for_broken_modules
-    can_import_enum_variant
     type_var_cycles_resolve_completely
     type_var_cycles_resolve_as_possible
     type_var_resolves_to_int_var
-    glob_enum
-    glob_across_crates
-    std_prelude
     match_ergonomics_ref
     infer_while_let
-    macro_rules_from_other_crates_are_visible_with_macro_use
-    prelude_is_macro_use
     coerce_merge_fail_fallback
-    macro_dollar_crate_self
-    macro_dollar_crate_other
 );
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs
index 8d98f88ce1..ab97a09b91 100644
--- a/crates/ra_hir/src/mock.rs
+++ b/crates/ra_hir/src/mock.rs
@@ -77,12 +77,6 @@ impl MockDatabase {
         (db, source_root, file_id)
     }
 
-    pub fn with_position(fixture: &str) -> (MockDatabase, FilePosition) {
-        let (db, position) = MockDatabase::from_fixture(fixture);
-        let position = position.expect("expected a marker ( <|> )");
-        (db, position)
-    }
-
     pub fn file_id_of(&self, path: &str) -> FileId {
         match self.files.get(path) {
             Some(it) => *it,
@@ -90,25 +84,6 @@ impl MockDatabase {
         }
     }
 
-    pub fn set_crate_graph_from_fixture(&mut self, graph: CrateGraphFixture) {
-        let mut ids = FxHashMap::default();
-        let mut crate_graph = CrateGraph::default();
-        for (crate_name, (crate_root, edition, cfg_options, _)) in graph.0.iter() {
-            let crate_root = self.file_id_of(&crate_root);
-            let crate_id = crate_graph.add_crate_root(crate_root, *edition, cfg_options.clone());
-            Arc::make_mut(&mut self.crate_names).insert(crate_id, crate_name.clone());
-            ids.insert(crate_name, crate_id);
-        }
-        for (crate_name, (_, _, _, deps)) in graph.0.iter() {
-            let from = ids[crate_name];
-            for dep in deps {
-                let to = ids[dep];
-                crate_graph.add_dep(from, dep.as_str().into(), to).unwrap();
-            }
-        }
-        self.set_crate_graph(Arc::new(crate_graph))
-    }
-
     pub fn diagnostics(&self) -> String {
         let mut buf = String::new();
         let mut files: Vec<FileId> = self.files.values().copied().collect();
@@ -285,46 +260,3 @@ impl MockDatabase {
             .collect()
     }
 }
-
-#[derive(Default)]
-pub struct CrateGraphFixture(pub Vec<(String, (String, Edition, CfgOptions, Vec<String>))>);
-
-#[macro_export]
-macro_rules! crate_graph {
-    ($(
-        $crate_name:literal: (
-            $crate_path:literal,
-            $($edition:literal,)?
-            [$($dep:literal),*]
-            $(, cfg = {
-                $($key:literal $(= $value:literal)?),*
-                $(,)?
-            })?
-        ),
-    )*) => {{
-        let mut res = $crate::mock::CrateGraphFixture::default();
-        $(
-            #[allow(unused_mut, unused_assignments)]
-            let mut edition = ra_db::Edition::Edition2018;
-            $(edition = ra_db::Edition::from_string($edition);)?
-            let cfg_options = {
-                #[allow(unused_mut)]
-                let mut cfg = ::ra_cfg::CfgOptions::default();
-                $(
-                    $(
-                        if 0 == 0 $(+ { drop($value); 1})? {
-                            cfg.insert_atom($key.into());
-                        }
-                        $(cfg.insert_key_value($key.into(), $value.into());)?
-                    )*
-                )?
-                cfg
-            };
-            res.0.push((
-                $crate_name.to_string(),
-                ($crate_path.to_string(), edition, cfg_options, vec![$($dep.to_string()),*])
-            ));
-        )*
-        res
-    }}
-}
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
index 95062ef6c4..3d5f18bfae 100644
--- a/crates/ra_syntax/src/ast/make.rs
+++ b/crates/ra_syntax/src/ast/make.rs
@@ -110,23 +110,6 @@ pub fn match_arm_list(arms: impl Iterator<Item = ast::MatchArm>) -> ast::MatchAr
     }
 }
 
-pub fn let_match_early(expr: ast::Expr, path: &str, early_expression: &str) -> ast::LetStmt {
-    return from_text(&format!(
-        r#"let {} = match {} {{
-    {}(it) => it,
-    None => {},
-}};"#,
-        expr.syntax().text(),
-        expr.syntax().text(),
-        path,
-        early_expression
-    ));
-
-    fn from_text(text: &str) -> ast::LetStmt {
-        ast_from_text(&format!("fn f() {{ {} }}", text))
-    }
-}
-
 pub fn where_pred(path: ast::Path, bounds: impl Iterator<Item = ast::TypeBound>) -> ast::WherePred {
     let bounds = bounds.map(|b| b.syntax().to_string()).join(" + ");
     return from_text(&format!("{}: {}", path.syntax(), bounds));


Test patch:
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index f271557377..4b7e34878a 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -2,8 +2,7 @@ use std::fmt::Write;
 use std::sync::Arc;
 
 use insta::assert_snapshot;
-
-use ra_db::{salsa::Database, FilePosition, SourceDatabase};
+use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase};
 use ra_syntax::{
     algo,
     ast::{self, AstNode},
@@ -25,9 +24,9 @@ mod coercion;
 
 #[test]
 fn cfg_impl_block() {
-    let (mut db, pos) = MockDatabase::with_position(
+    let (db, pos) = MockDatabase::with_position(
         r#"
-//- /main.rs
+//- /main.rs crate:main deps:foo cfg:test
 use foo::S as T;
 struct S;
 
@@ -46,7 +45,7 @@ fn test() {
     t<|>;
 }
 
-//- /foo.rs
+//- /foo.rs crate:foo
 struct S;
 
 #[cfg(not(test))]
@@ -60,18 +59,14 @@ impl S {
 }
 "#,
     );
-    db.set_crate_graph_from_fixture(crate_graph! {
-        "main": ("/main.rs", ["foo"], cfg = { "test" }),
-        "foo": ("/foo.rs", []),
-    });
     assert_eq!("(i32, {unknown}, i32, {unknown})", type_at_pos(&db, pos));
 }
 
 #[test]
 fn infer_await() {
-    let (mut db, pos) = MockDatabase::with_position(
+    let (db, pos) = MockDatabase::with_position(
         r#"
-//- /main.rs
+//- /main.rs crate:main deps:std
 
 struct IntFuture;
 
@@ -85,7 +80,7 @@ fn test() {
     v<|>;
 }
 
-//- /std.rs
+//- /std.rs crate:std
 #[prelude_import] use future::*;
 mod future {
     trait Future {
@@ -95,18 +90,14 @@ mod future {
 
 "#,
     );
-    db.set_crate_graph_from_fixture(crate_graph! {
-        "main": ("/main.rs", ["std"]),
-        "std": ("/std.rs", []),
-    });
     assert_eq!("u64", type_at_pos(&db, pos));
 }
 
 #[test]
 fn infer_box() {
-    let (mut db, pos) = MockDatabase::with_position(
+    let (db, pos) = MockDatabase::with_position(
         r#"
-//- /main.rs
+//- /main.rs crate:main deps:std
 
 fn test() {
     let x = box 1;
@@ -114,7 +105,7 @@ fn test() {
     t<|>;
 }
 
-//- /std.rs
+//- /std.rs crate:std
 #[prelude_import] use prelude::*;
 mod prelude {}
 
@@ -126,10 +117,6 @@ mod boxed {
 
 "#,
     );
-    db.set_crate_graph_from_fixture(crate_graph! {
-        "main": ("/main.rs", ["std"]),
-        "std": ("/std.rs", []),
-    });
     assert_eq!("(Box<i32>, Box<Box<i32>>, Box<&i32>, Box<[i32;_]>)", type_at_pos(&db, pos));
 }
 
@@ -154,9 +141,9 @@ fn test() {
 
 #[test]
 fn infer_try() {
-    let (mut db, pos) = MockDatabase::with_position(
+    let (db, pos) = MockDatabase::with_position(
         r#"
-//- /main.rs
+//- /main.rs crate:main deps:std
 
 fn test() {
     let r: Result<i32, u64> = Result::Ok(1);
@@ -164,7 +151,7 @@ fn test() {
     v<|>;
 }
 
-//- /std.rs
+//- /std.rs crate:std
 
 #[prelude_import] use ops::*;
 mod ops {
@@ -189,18 +176,14 @@ mod result {
 
 "#,
     );
-    db.set_crate_graph_from_fixture(crate_graph! {
-        "main": ("/main.rs", ["std"]),
-        "std": ("/std.rs", []),
-    });
     assert_eq!("i32", type_at_pos(&db, pos));
 }
 
 #[test]
 fn infer_for_loop() {
-    let (mut db, pos) = MockDatabase::with_position(
+    let (db, pos) = MockDatabase::with_position(
         r#"
-//- /main.rs
+//- /main.rs crate:main deps:std
 
 use std::collections::Vec;
 
@@ -212,7 +195,7 @@ fn test() {
     }
 }
 
-//- /std.rs
+//- /std.rs crate:std
 
 #[prelude_import] use iter::*;
 mod iter {
@@ -234,10 +217,6 @@ mod collections {
 }
 "#,
     );
-    db.set_crate_graph_from_fixture(crate_graph! {
-        "main": ("/main.rs", ["std"]),
-        "std": ("/std.rs", []),
-    });
     assert_eq!("&str", type_at_pos(&db, pos));
 }
 
@@ -2505,15 +2484,15 @@ pub fn main_loop() {
 
 #[test]
 fn cross_crate_associated_method_call() {
-    let (mut db, pos) = MockDatabase::with_position(
+    let (db, pos) = MockDatabase::with_position(
         r#"
-//- /main.rs
+//- /main.rs crate:main deps:other_crate
 fn test() {
     let x = other_crate::foo::S::thing();
     x<|>;
 }
 
-//- /lib.rs
+//- /lib.rs crate:other_crate
 mod foo {
     struct S;
     impl S {
@@ -2522,10 +2501,6 @@ mod foo {
 }
 "#,
     );
-    db.set_crate_graph_from_fixture(crate_graph! {
-        "main": ("/main.rs", ["other_crate"]),
-        "other_crate": ("/lib.rs", []),
-    });
     assert_eq!("i128", type_at_pos(&db, pos));
 }
 
@@ -3403,16 +3378,15 @@ fn test() { S.foo()<|>; }
 
 #[test]
 fn infer_macro_with_dollar_crate_is_correct_in_expr() {
-    // covers!(macro_dollar_crate_other);
-    let (mut db, pos) = MockDatabase::with_position(
+    let (db, pos) = MockDatabase::with_position(
         r#"
-//- /main.rs
+//- /main.rs crate:main deps:foo
 fn test() {
     let x = (foo::foo!(1), foo::foo!(2));
     x<|>;
 }
 
-//- /lib.rs
+//- /lib.rs crate:foo
 #[macro_export]
 macro_rules! foo {
     (1) => { $crate::bar!() };
@@ -3427,10 +3401,6 @@ macro_rules! bar {
 pub fn baz() -> usize { 31usize }
 "#,
     );
-    db.set_crate_graph_from_fixture(crate_graph! {
-        "main": ("/main.rs", ["foo"]),
-        "foo": ("/lib.rs", []),
-    });
     assert_eq!("(i32, usize)", type_at_pos(&db, pos));
 }
 
@@ -3512,9 +3482,9 @@ fn test() { (&S).foo()<|>; }
 
 #[test]
 fn method_resolution_trait_from_prelude() {
-    let (mut db, pos) = MockDatabase::with_position(
+    let (db, pos) = MockDatabase::with_position(
         r#"
-//- /main.rs
+//- /main.rs crate:main deps:other_crate
 struct S;
 impl Clone for S {}
 
@@ -3522,7 +3492,7 @@ fn test() {
     S.clone()<|>;
 }
 
-//- /lib.rs
+//- /lib.rs crate:other_crate
 #[prelude_import] use foo::*;
 
 mod foo {
@@ -3532,10 +3502,6 @@ mod foo {
 }
 "#,
     );
-    db.set_crate_graph_from_fixture(crate_graph! {
-        "main": ("/main.rs", ["other_crate"]),
-        "other_crate": ("/lib.rs", []),
-    });
     assert_eq!("S", type_at_pos(&db, pos));
 }