aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/handlers')
-rw-r--r--crates/ra_assists/src/handlers/auto_import.rs42
-rw-r--r--crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs2
-rw-r--r--crates/ra_assists/src/handlers/unwrap_block.rs67
3 files changed, 69 insertions, 42 deletions
diff --git a/crates/ra_assists/src/handlers/auto_import.rs b/crates/ra_assists/src/handlers/auto_import.rs
index 99682e023..db6c4d2fa 100644
--- a/crates/ra_assists/src/handlers/auto_import.rs
+++ b/crates/ra_assists/src/handlers/auto_import.rs
@@ -45,15 +45,12 @@ pub(crate) fn auto_import(ctx: AssistCtx) -> Option<Assist> {
45 return None; 45 return None;
46 } 46 }
47 47
48 let range = ctx.sema.original_range(&auto_import_assets.syntax_under_caret).range;
48 let mut group = ctx.add_assist_group(auto_import_assets.get_import_group_message()); 49 let mut group = ctx.add_assist_group(auto_import_assets.get_import_group_message());
49 for import in proposed_imports { 50 for import in proposed_imports {
50 group.add_assist(AssistId("auto_import"), format!("Import `{}`", &import), |edit| { 51 group.add_assist(AssistId("auto_import"), format!("Import `{}`", &import), |edit| {
51 edit.target(auto_import_assets.syntax_under_caret.text_range()); 52 edit.target(range);
52 insert_use_statement( 53 insert_use_statement(&auto_import_assets.syntax_under_caret, &import, edit);
53 &auto_import_assets.syntax_under_caret,
54 &import,
55 edit.text_edit_builder(),
56 );
57 }); 54 });
58 } 55 }
59 group.finish() 56 group.finish()
@@ -68,10 +65,10 @@ struct AutoImportAssets {
68 65
69impl AutoImportAssets { 66impl AutoImportAssets {
70 fn new(ctx: &AssistCtx) -> Option<Self> { 67 fn new(ctx: &AssistCtx) -> Option<Self> {
71 if let Some(path_under_caret) = ctx.find_node_at_offset::<ast::Path>() { 68 if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::<ast::Path>() {
72 Self::for_regular_path(path_under_caret, &ctx) 69 Self::for_regular_path(path_under_caret, &ctx)
73 } else { 70 } else {
74 Self::for_method_call(ctx.find_node_at_offset()?, &ctx) 71 Self::for_method_call(ctx.find_node_at_offset_with_descend()?, &ctx)
75 } 72 }
76 } 73 }
77 74
@@ -306,6 +303,35 @@ mod tests {
306 } 303 }
307 304
308 #[test] 305 #[test]
306 fn applicable_when_found_an_import_in_macros() {
307 check_assist(
308 auto_import,
309 r"
310 macro_rules! foo {
311 ($i:ident) => { fn foo(a: $i) {} }
312 }
313 foo!(Pub<|>Struct);
314
315 pub mod PubMod {
316 pub struct PubStruct;
317 }
318 ",
319 r"
320 use PubMod::PubStruct;
321
322 macro_rules! foo {
323 ($i:ident) => { fn foo(a: $i) {} }
324 }
325 foo!(Pub<|>Struct);
326
327 pub mod PubMod {
328 pub struct PubStruct;
329 }
330 ",
331 );
332 }
333
334 #[test]
309 fn auto_imports_are_merged() { 335 fn auto_imports_are_merged() {
310 check_assist( 336 check_assist(
311 auto_import, 337 auto_import,
diff --git a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
index 918e8dd8d..ff2463c77 100644
--- a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
@@ -38,7 +38,7 @@ pub(crate) fn replace_qualified_name_with_use(ctx: AssistCtx) -> Option<Assist>
38 "Replace qualified path with use", 38 "Replace qualified path with use",
39 |edit| { 39 |edit| {
40 let path_to_import = hir_path.mod_path().clone(); 40 let path_to_import = hir_path.mod_path().clone();
41 insert_use_statement(path.syntax(), &path_to_import, edit.text_edit_builder()); 41 insert_use_statement(path.syntax(), &path_to_import, edit);
42 42
43 if let Some(last) = path.segment() { 43 if let Some(last) = path.segment() {
44 // Here we are assuming the assist will provide a correct use statement 44 // Here we are assuming the assist will provide a correct use statement
diff --git a/crates/ra_assists/src/handlers/unwrap_block.rs b/crates/ra_assists/src/handlers/unwrap_block.rs
index 58649c47e..859c70ad8 100644
--- a/crates/ra_assists/src/handlers/unwrap_block.rs
+++ b/crates/ra_assists/src/handlers/unwrap_block.rs
@@ -1,8 +1,8 @@
1use crate::{Assist, AssistCtx, AssistId}; 1use crate::{Assist, AssistCtx, AssistId};
2 2
3use ast::{BlockExpr, Expr, ForExpr, IfExpr, LoopBodyOwner, LoopExpr, WhileExpr}; 3use ast::LoopBodyOwner;
4use ra_fmt::unwrap_trivial_block; 4use ra_fmt::unwrap_trivial_block;
5use ra_syntax::{ast, AstNode, TextRange, T}; 5use ra_syntax::{ast, match_ast, AstNode, TextRange, T};
6 6
7// Assist: unwrap_block 7// Assist: unwrap_block
8// 8//
@@ -23,39 +23,40 @@ use ra_syntax::{ast, AstNode, TextRange, T};
23// ``` 23// ```
24pub(crate) fn unwrap_block(ctx: AssistCtx) -> Option<Assist> { 24pub(crate) fn unwrap_block(ctx: AssistCtx) -> Option<Assist> {
25 let l_curly_token = ctx.find_token_at_offset(T!['{'])?; 25 let l_curly_token = ctx.find_token_at_offset(T!['{'])?;
26 26 let block = ast::BlockExpr::cast(l_curly_token.parent())?;
27 let res = if let Some(if_expr) = l_curly_token.ancestors().find_map(IfExpr::cast) { 27 let parent = block.syntax().parent()?;
28 // if expression 28 let (expr, expr_to_unwrap) = match_ast! {
29 let expr_to_unwrap = if_expr.blocks().find_map(|expr| extract_expr(ctx.frange.range, expr)); 29 match parent {
30 let expr_to_unwrap = expr_to_unwrap?; 30 ast::IfExpr(if_expr) => {
31 // Find if we are in a else if block 31 let expr_to_unwrap = if_expr.blocks().find_map(|expr| extract_expr(ctx.frange.range, expr));
32 let ancestor = if_expr.syntax().ancestors().skip(1).find_map(ast::IfExpr::cast); 32 let expr_to_unwrap = expr_to_unwrap?;
33 33 // Find if we are in a else if block
34 if let Some(ancestor) = ancestor { 34 let ancestor = if_expr.syntax().parent().and_then(ast::IfExpr::cast);
35 Some((ast::Expr::IfExpr(ancestor), expr_to_unwrap)) 35
36 } else { 36 match ancestor {
37 Some((ast::Expr::IfExpr(if_expr), expr_to_unwrap)) 37 None => (ast::Expr::IfExpr(if_expr), expr_to_unwrap),
38 Some(ancestor) => (ast::Expr::IfExpr(ancestor), expr_to_unwrap),
39 }
40 },
41 ast::ForExpr(for_expr) => {
42 let block_expr = for_expr.loop_body()?;
43 let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?;
44 (ast::Expr::ForExpr(for_expr), expr_to_unwrap)
45 },
46 ast::WhileExpr(while_expr) => {
47 let block_expr = while_expr.loop_body()?;
48 let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?;
49 (ast::Expr::WhileExpr(while_expr), expr_to_unwrap)
50 },
51 ast::LoopExpr(loop_expr) => {
52 let block_expr = loop_expr.loop_body()?;
53 let expr_to_unwrap = extract_expr(ctx.frange.range, block_expr)?;
54 (ast::Expr::LoopExpr(loop_expr), expr_to_unwrap)
55 },
56 _ => return None,
38 } 57 }
39 } else if let Some(for_expr) = l_curly_token.ancestors().find_map(ForExpr::cast) {
40 // for expression
41 let block_expr = for_expr.loop_body()?;
42 extract_expr(ctx.frange.range, block_expr)
43 .map(|expr_to_unwrap| (ast::Expr::ForExpr(for_expr), expr_to_unwrap))
44 } else if let Some(while_expr) = l_curly_token.ancestors().find_map(WhileExpr::cast) {
45 // while expression
46 let block_expr = while_expr.loop_body()?;
47 extract_expr(ctx.frange.range, block_expr)
48 .map(|expr_to_unwrap| (ast::Expr::WhileExpr(while_expr), expr_to_unwrap))
49 } else if let Some(loop_expr) = l_curly_token.ancestors().find_map(LoopExpr::cast) {
50 // loop expression
51 let block_expr = loop_expr.loop_body()?;
52 extract_expr(ctx.frange.range, block_expr)
53 .map(|expr_to_unwrap| (ast::Expr::LoopExpr(loop_expr), expr_to_unwrap))
54 } else {
55 None
56 }; 58 };
57 59
58 let (expr, expr_to_unwrap) = res?;
59 ctx.add_assist(AssistId("unwrap_block"), "Unwrap block", |edit| { 60 ctx.add_assist(AssistId("unwrap_block"), "Unwrap block", |edit| {
60 edit.set_cursor(expr.syntax().text_range().start()); 61 edit.set_cursor(expr.syntax().text_range().start());
61 edit.target(expr_to_unwrap.syntax().text_range()); 62 edit.target(expr_to_unwrap.syntax().text_range());
@@ -76,7 +77,7 @@ pub(crate) fn unwrap_block(ctx: AssistCtx) -> Option<Assist> {
76 }) 77 })
77} 78}
78 79
79fn extract_expr(cursor_range: TextRange, block: BlockExpr) -> Option<Expr> { 80fn extract_expr(cursor_range: TextRange, block: ast::BlockExpr) -> Option<ast::Expr> {
80 let cursor_in_range = block.l_curly_token()?.text_range().contains_range(cursor_range); 81 let cursor_in_range = block.l_curly_token()?.text_range().contains_range(cursor_range);
81 82
82 if cursor_in_range { 83 if cursor_in_range {