From 9b2bd022dc6fbe13356622ada5b6499f012cb5ae Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 10:17:46 +0200 Subject: Snippetify add_new --- crates/ra_assists/src/handlers/add_new.rs | 56 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'crates/ra_assists/src/handlers') diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/add_new.rs index fe7451dcf..837aa8377 100644 --- a/crates/ra_assists/src/handlers/add_new.rs +++ b/crates/ra_assists/src/handlers/add_new.rs @@ -3,7 +3,7 @@ use ra_syntax::{ ast::{ self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner, }, - TextSize, T, + T, }; use stdx::{format_to, SepBy}; @@ -25,7 +25,7 @@ use crate::{AssistContext, AssistId, Assists}; // } // // impl Ctx { -// fn new(data: T) -> Self { Self { data } } +// fn $0new(data: T) -> Self { Self { data } } // } // // ``` @@ -42,31 +42,26 @@ pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { let impl_def = find_struct_impl(&ctx, &strukt)?; let target = strukt.syntax().text_range(); - acc.add(AssistId("add_new"), "Add default constructor", target, |edit| { + acc.add(AssistId("add_new"), "Add default constructor", target, |builder| { let mut buf = String::with_capacity(512); if impl_def.is_some() { buf.push('\n'); } - let vis = strukt.visibility().map(|v| format!("{} ", v)); - let vis = vis.as_deref().unwrap_or(""); + let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v)); let params = field_list .fields() .filter_map(|f| { - Some(format!( - "{}: {}", - f.name()?.syntax().text(), - f.ascribed_type()?.syntax().text() - )) + Some(format!("{}: {}", f.name()?.syntax(), f.ascribed_type()?.syntax())) }) .sep_by(", "); let fields = field_list.fields().filter_map(|f| f.name()).sep_by(", "); format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields); - let (start_offset, end_offset) = impl_def + let start_offset = impl_def .and_then(|impl_def| { buf.push('\n'); let start = impl_def @@ -76,17 +71,20 @@ pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { .text_range() .end(); - Some((start, TextSize::of("\n"))) + Some(start) }) .unwrap_or_else(|| { buf = generate_impl_text(&strukt, &buf); - let start = strukt.syntax().text_range().end(); - - (start, TextSize::of("\n}\n")) + strukt.syntax().text_range().end() }); - edit.set_cursor(start_offset + TextSize::of(&buf) - end_offset); - edit.insert(start_offset, buf); + match ctx.config.snippet_cap { + None => builder.insert(start_offset, buf), + Some(cap) => { + buf = buf.replace("fn new", "fn $0new"); + builder.insert_snippet(cap, start_offset, buf); + } + } }) } @@ -191,7 +189,7 @@ mod tests { "struct Foo {} impl Foo { - fn new() -> Self { Self { } }<|> + fn $0new() -> Self { Self { } } } ", ); @@ -201,7 +199,7 @@ impl Foo { "struct Foo {} impl Foo { - fn new() -> Self { Self { } }<|> + fn $0new() -> Self { Self { } } } ", ); @@ -211,7 +209,7 @@ impl Foo { "struct Foo<'a, T: Foo<'a>> {} impl<'a, T: Foo<'a>> Foo<'a, T> { - fn new() -> Self { Self { } }<|> + fn $0new() -> Self { Self { } } } ", ); @@ -221,7 +219,7 @@ impl<'a, T: Foo<'a>> Foo<'a, T> { "struct Foo { baz: String } impl Foo { - fn new(baz: String) -> Self { Self { baz } }<|> + fn $0new(baz: String) -> Self { Self { baz } } } ", ); @@ -231,7 +229,7 @@ impl Foo { "struct Foo { baz: String, qux: Vec } impl Foo { - fn new(baz: String, qux: Vec) -> Self { Self { baz, qux } }<|> + fn $0new(baz: String, qux: Vec) -> Self { Self { baz, qux } } } ", ); @@ -243,7 +241,7 @@ impl Foo { "struct Foo { pub baz: String, pub qux: Vec } impl Foo { - fn new(baz: String, qux: Vec) -> Self { Self { baz, qux } }<|> + fn $0new(baz: String, qux: Vec) -> Self { Self { baz, qux } } } ", ); @@ -258,7 +256,7 @@ impl Foo {} "struct Foo {} impl Foo { - fn new() -> Self { Self { } }<|> + fn $0new() -> Self { Self { } } } ", ); @@ -273,7 +271,7 @@ impl Foo { "struct Foo {} impl Foo { - fn new() -> Self { Self { } }<|> + fn $0new() -> Self { Self { } } fn qux(&self) {} } @@ -294,7 +292,7 @@ impl Foo { "struct Foo {} impl Foo { - fn new() -> Self { Self { } }<|> + fn $0new() -> Self { Self { } } fn qux(&self) {} fn baz() -> i32 { @@ -311,7 +309,7 @@ impl Foo { "pub struct Foo {} impl Foo { - pub fn new() -> Self { Self { } }<|> + pub fn $0new() -> Self { Self { } } } ", ); @@ -321,7 +319,7 @@ impl Foo { "pub(crate) struct Foo {} impl Foo { - pub(crate) fn new() -> Self { Self { } }<|> + pub(crate) fn $0new() -> Self { Self { } } } ", ); @@ -414,7 +412,7 @@ pub struct Source { } impl Source { - pub fn new(file_id: HirFileId, ast: T) -> Self { Self { file_id, ast } }<|> + pub fn $0new(file_id: HirFileId, ast: T) -> Self { Self { file_id, ast } } pub fn map U, U>(self, f: F) -> Source { Source { file_id: self.file_id, ast: f(self.ast) } -- cgit v1.2.3 From 45e343a0ef6f4caf078811d0664907610f085d54 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 10:20:21 +0200 Subject: Minor --- crates/ra_assists/src/handlers/auto_import.rs | 7 ++++++- crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'crates/ra_assists/src/handlers') diff --git a/crates/ra_assists/src/handlers/auto_import.rs b/crates/ra_assists/src/handlers/auto_import.rs index 78d23150d..f6d25579e 100644 --- a/crates/ra_assists/src/handlers/auto_import.rs +++ b/crates/ra_assists/src/handlers/auto_import.rs @@ -50,7 +50,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> format!("Import `{}`", &import), range, |builder| { - insert_use_statement(&auto_import_assets.syntax_under_caret, &import, ctx, builder); + insert_use_statement( + &auto_import_assets.syntax_under_caret, + &import, + ctx, + builder.text_edit_builder(), + ); }, ); } 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 1a81d8a0e..d9f84208d 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 @@ -39,7 +39,7 @@ pub(crate) fn replace_qualified_name_with_use( target, |builder| { let path_to_import = hir_path.mod_path().clone(); - insert_use_statement(path.syntax(), &path_to_import, ctx, builder); + insert_use_statement(path.syntax(), &path_to_import, ctx, builder.text_edit_builder()); if let Some(last) = path.segment() { // Here we are assuming the assist will provide a correct use statement -- cgit v1.2.3 From 36a5ca9a843aa807b8152d4c5631be605fc80e80 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 10:26:14 +0200 Subject: Minor --- crates/ra_assists/src/handlers/change_return_type_to_result.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'crates/ra_assists/src/handlers') diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs index 5c907097e..c2ea87dd7 100644 --- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs +++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs @@ -19,8 +19,7 @@ use crate::{AssistContext, AssistId, Assists}; // fn foo() -> Result { Ok(42i32) } // ``` pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { - let fn_def = ctx.find_node_at_offset::(); - let fn_def = &mut fn_def?; + let fn_def = ctx.find_node_at_offset::()?; let ret_type = &fn_def.ret_type()?.type_ref()?; if ret_type.syntax().text().to_string().starts_with("Result<") { return None; -- cgit v1.2.3 From 2e74df4e2b79955a44dee79811e06b8fabff4da2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 10:28:58 +0200 Subject: Cleanup --- .../src/handlers/change_return_type_to_result.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'crates/ra_assists/src/handlers') diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs index c2ea87dd7..ae8237c5d 100644 --- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs +++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs @@ -19,23 +19,21 @@ use crate::{AssistContext, AssistId, Assists}; // fn foo() -> Result { Ok(42i32) } // ``` pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { - let fn_def = ctx.find_node_at_offset::()?; - let ret_type = &fn_def.ret_type()?.type_ref()?; - if ret_type.syntax().text().to_string().starts_with("Result<") { + let ret_type = ctx.find_node_at_offset::()?; + // FIXME: extend to lambdas as well + let fn_def = ret_type.syntax().parent().and_then(ast::FnDef::cast)?; + + let type_ref = &ret_type.type_ref()?; + if type_ref.syntax().text().to_string().starts_with("Result<") { return None; } let block_expr = &fn_def.body()?; - let cursor_in_ret_type = - fn_def.ret_type()?.syntax().text_range().contains_range(ctx.frange.range); - if !cursor_in_ret_type { - return None; - } acc.add( AssistId("change_return_type_to_result"), "Change return type to Result", - ret_type.syntax().text_range(), + type_ref.syntax().text_range(), |edit| { let mut tail_return_expr_collector = TailReturnCollector::new(); tail_return_expr_collector.collect_jump_exprs(block_expr, false); @@ -44,10 +42,10 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { edit.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); } - edit.replace_node_and_indent(ret_type.syntax(), format!("Result<{}, >", ret_type)); + edit.replace_node_and_indent(type_ref.syntax(), format!("Result<{}, >", type_ref)); - if let Some(node_start) = result_insertion_offset(&ret_type) { - edit.set_cursor(node_start + TextSize::of(&format!("Result<{}, ", ret_type))); + if let Some(node_start) = result_insertion_offset(&type_ref) { + edit.set_cursor(node_start + TextSize::of(&format!("Result<{}, ", type_ref))); } }, ) -- cgit v1.2.3 From d790a443f396ad53037a3f6ba794b6f4df5b3748 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 10:30:18 +0200 Subject: wip --- .../ra_assists/src/handlers/change_return_type_to_result.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'crates/ra_assists/src/handlers') diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs index ae8237c5d..c9f909f9c 100644 --- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs +++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs @@ -34,18 +34,22 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex AssistId("change_return_type_to_result"), "Change return type to Result", type_ref.syntax().text_range(), - |edit| { + |builder| { let mut tail_return_expr_collector = TailReturnCollector::new(); tail_return_expr_collector.collect_jump_exprs(block_expr, false); tail_return_expr_collector.collect_tail_exprs(block_expr); for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { - edit.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); + builder.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); } - edit.replace_node_and_indent(type_ref.syntax(), format!("Result<{}, >", type_ref)); + match ctx.config.snippet_cap { + Some(_) => {} + None => {} + } + builder.replace_node_and_indent(type_ref.syntax(), format!("Result<{}, >", type_ref)); if let Some(node_start) = result_insertion_offset(&type_ref) { - edit.set_cursor(node_start + TextSize::of(&format!("Result<{}, ", type_ref))); + builder.set_cursor(node_start + TextSize::of(&format!("Result<{}, ", type_ref))); } }, ) -- cgit v1.2.3 From 33e111483fbc80c017037e0b158ee652ed41b3e8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 May 2020 11:10:15 +0200 Subject: Use snippets in change_return_type_to_result --- .../src/handlers/change_return_type_to_result.rs | 81 ++++++++++------------ 1 file changed, 35 insertions(+), 46 deletions(-) (limited to 'crates/ra_assists/src/handlers') diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs index c9f909f9c..c6baa0a57 100644 --- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs +++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs @@ -1,8 +1,6 @@ use ra_syntax::{ ast::{self, BlockExpr, Expr, LoopBodyOwner}, - AstNode, - SyntaxKind::{COMMENT, WHITESPACE}, - SyntaxNode, TextSize, + AstNode, SyntaxNode, }; use crate::{AssistContext, AssistId, Assists}; @@ -16,7 +14,7 @@ use crate::{AssistContext, AssistId, Assists}; // ``` // -> // ``` -// fn foo() -> Result { Ok(42i32) } +// fn foo() -> Result { Ok(42i32) } // ``` pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { let ret_type = ctx.find_node_at_offset::()?; @@ -42,14 +40,14 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { builder.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); } - match ctx.config.snippet_cap { - Some(_) => {} - None => {} - } - builder.replace_node_and_indent(type_ref.syntax(), format!("Result<{}, >", type_ref)); - if let Some(node_start) = result_insertion_offset(&type_ref) { - builder.set_cursor(node_start + TextSize::of(&format!("Result<{}, ", type_ref))); + match ctx.config.snippet_cap { + Some(cap) => { + let snippet = format!("Result<{}, ${{0:_}}>", type_ref); + builder.replace_snippet(cap, type_ref.syntax().text_range(), snippet) + } + None => builder + .replace(type_ref.syntax().text_range(), format!("Result<{}, _>", type_ref)), } }, ) @@ -251,17 +249,8 @@ fn get_tail_expr_from_block(expr: &Expr) -> Option> { } } -fn result_insertion_offset(ret_type: &ast::TypeRef) -> Option { - let non_ws_child = ret_type - .syntax() - .children_with_tokens() - .find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?; - Some(non_ws_child.text_range().start()) -} - #[cfg(test)] mod tests { - use crate::tests::{check_assist, check_assist_not_applicable}; use super::*; @@ -274,7 +263,7 @@ mod tests { let test = "test"; return 42i32; }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let test = "test"; return Ok(42i32); }"#, @@ -289,7 +278,7 @@ mod tests { let test = "test"; return 42i32; }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let test = "test"; return Ok(42i32); }"#, @@ -315,7 +304,7 @@ mod tests { let test = "test"; return 42i32; }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let test = "test"; return Ok(42i32); }"#, @@ -330,7 +319,7 @@ mod tests { let test = "test"; 42i32 }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let test = "test"; Ok(42i32) }"#, @@ -344,7 +333,7 @@ mod tests { r#"fn foo() -> i32<|> { 42i32 }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { Ok(42i32) }"#, ); @@ -360,7 +349,7 @@ mod tests { 24i32 } }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { if true { Ok(42i32) } else { @@ -385,7 +374,7 @@ mod tests { 24i32 } }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { if true { if false { Ok(1) @@ -414,7 +403,7 @@ mod tests { 24i32.await } }"#, - r#"async fn foo() -> Result> { + r#"async fn foo() -> Result { if true { if false { Ok(1.await) @@ -435,7 +424,7 @@ mod tests { r#"fn foo() -> [i32;<|> 3] { [1, 2, 3] }"#, - r#"fn foo() -> Result<[i32; 3], <|>> { + r#"fn foo() -> Result<[i32; 3], ${0:_}> { Ok([1, 2, 3]) }"#, ); @@ -456,7 +445,7 @@ mod tests { 24 as i32 } }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { if true { if false { Ok(1 as i32) @@ -481,7 +470,7 @@ mod tests { _ => 24i32, } }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let my_var = 5; match my_var { 5 => Ok(42i32), @@ -504,7 +493,7 @@ mod tests { my_var }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let my_var = 5; loop { println!("test"); @@ -527,7 +516,7 @@ mod tests { my_var }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let my_var = let x = loop { break 1; }; @@ -550,7 +539,7 @@ mod tests { res }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let my_var = 5; let res = match my_var { 5 => 42i32, @@ -573,7 +562,7 @@ mod tests { res }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let my_var = 5; let res = if my_var == 5 { 42i32 @@ -609,7 +598,7 @@ mod tests { }, } }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let my_var = 5; match my_var { 5 => { @@ -642,7 +631,7 @@ mod tests { } 53i32 }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let test = "test"; if test == "test" { return Ok(24i32); @@ -673,7 +662,7 @@ mod tests { the_field }"#, - r#"fn foo(the_field: u32) -> Result> { + r#"fn foo(the_field: u32) -> Result { let true_closure = || { return true; }; @@ -712,7 +701,7 @@ mod tests { t.unwrap_or_else(|| the_field) }"#, - r#"fn foo(the_field: u32) -> Result> { + r#"fn foo(the_field: u32) -> Result { let true_closure = || { return true; }; @@ -750,7 +739,7 @@ mod tests { i += 1; } }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let test = "test"; if test == "test" { return Ok(24i32); @@ -782,7 +771,7 @@ mod tests { } } }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let test = "test"; if test == "test" { return Ok(24i32); @@ -820,7 +809,7 @@ mod tests { } } }"#, - r#"fn foo() -> Result> { + r#"fn foo() -> Result { let test = "test"; let other = 5; if test == "test" { @@ -861,7 +850,7 @@ mod tests { the_field }"#, - r#"fn foo(the_field: u32) -> Result> { + r#"fn foo(the_field: u32) -> Result { if the_field < 5 { let mut i = 0; loop { @@ -895,7 +884,7 @@ mod tests { the_field }"#, - r#"fn foo(the_field: u32) -> Result> { + r#"fn foo(the_field: u32) -> Result { if the_field < 5 { let mut i = 0; @@ -924,7 +913,7 @@ mod tests { the_field }"#, - r#"fn foo(the_field: u32) -> Result> { + r#"fn foo(the_field: u32) -> Result { if the_field < 5 { let mut i = 0; @@ -954,7 +943,7 @@ mod tests { the_field }"#, - r#"fn foo(the_field: u32) -> Result> { + r#"fn foo(the_field: u32) -> Result { if the_field < 5 { let mut i = 0; -- cgit v1.2.3