when generating new function, focus on return type instead of body

Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
This commit is contained in:
Benjamin Coenen
2020-10-04 21:21:30 +02:00
parent 636b413e14
commit 3bfa3e8123
3 changed files with 80 additions and 68 deletions

View File

@@ -36,8 +36,8 @@ use crate::{
// bar("", baz()); // bar("", baz());
// } // }
// //
// fn bar(arg: &str, baz: Baz) { // fn bar(arg: &str, baz: Baz) ${0:-> ()} {
// ${0:todo!()} // todo!()
// } // }
// //
// ``` // ```
@@ -80,9 +80,9 @@ pub(crate) fn generate_function(acc: &mut Assists, ctx: &AssistContext) -> Optio
struct FunctionTemplate { struct FunctionTemplate {
insert_offset: TextSize, insert_offset: TextSize,
placeholder_expr: ast::MacroCall,
leading_ws: String, leading_ws: String,
fn_def: ast::Fn, fn_def: ast::Fn,
ret_type: ast::RetType,
trailing_ws: String, trailing_ws: String,
file: FileId, file: FileId,
} }
@@ -90,11 +90,9 @@ struct FunctionTemplate {
impl FunctionTemplate { impl FunctionTemplate {
fn to_string(&self, cap: Option<SnippetCap>) -> String { fn to_string(&self, cap: Option<SnippetCap>) -> String {
let f = match cap { let f = match cap {
Some(cap) => render_snippet( Some(cap) => {
cap, render_snippet(cap, self.fn_def.syntax(), Cursor::Replace(self.ret_type.syntax()))
self.fn_def.syntax(), }
Cursor::Replace(self.placeholder_expr.syntax()),
),
None => self.fn_def.to_string(), None => self.fn_def.to_string(),
}; };
format!("{}{}{}", self.leading_ws, f, self.trailing_ws) format!("{}{}{}", self.leading_ws, f, self.trailing_ws)
@@ -141,8 +139,14 @@ impl FunctionBuilder {
let placeholder_expr = make::expr_todo(); let placeholder_expr = make::expr_todo();
let fn_body = make::block_expr(vec![], Some(placeholder_expr)); let fn_body = make::block_expr(vec![], Some(placeholder_expr));
let visibility = if self.needs_pub { Some(make::visibility_pub_crate()) } else { None }; let visibility = if self.needs_pub { Some(make::visibility_pub_crate()) } else { None };
let mut fn_def = let mut fn_def = make::fn_(
make::fn_(visibility, self.fn_name, self.type_params, self.params, fn_body); visibility,
self.fn_name,
self.type_params,
self.params,
fn_body,
Some(make::ret_type(make::ty("()"))),
);
let leading_ws; let leading_ws;
let trailing_ws; let trailing_ws;
@@ -163,12 +167,10 @@ impl FunctionBuilder {
} }
}; };
let placeholder_expr =
fn_def.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
FunctionTemplate { FunctionTemplate {
insert_offset, insert_offset,
placeholder_expr,
leading_ws, leading_ws,
ret_type: fn_def.ret_type().unwrap(),
fn_def, fn_def,
trailing_ws, trailing_ws,
file: self.file, file: self.file,
@@ -349,8 +351,8 @@ fn foo() {
bar(); bar();
} }
fn bar() { fn bar() ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -376,8 +378,8 @@ impl Foo {
} }
} }
fn bar() { fn bar() ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -400,8 +402,8 @@ fn foo1() {
bar(); bar();
} }
fn bar() { fn bar() ${0:-> ()} {
${0:todo!()} todo!()
} }
fn foo2() {} fn foo2() {}
@@ -426,8 +428,8 @@ mod baz {
bar(); bar();
} }
fn bar() { fn bar() ${0:-> ()} {
${0:todo!()} todo!()
} }
} }
", ",
@@ -452,8 +454,8 @@ fn foo() {
bar(baz()); bar(baz());
} }
fn bar(baz: Baz) { fn bar(baz: Baz) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
); );
@@ -485,8 +487,8 @@ impl Baz {
} }
} }
fn bar(baz: Baz) { fn bar(baz: Baz) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -506,8 +508,8 @@ fn foo() {
bar("bar") bar("bar")
} }
fn bar(arg: &str) { fn bar(arg: &str) ${0:-> ()} {
${0:todo!()} todo!()
} }
"#, "#,
) )
@@ -527,8 +529,8 @@ fn foo() {
bar('x') bar('x')
} }
fn bar(arg: char) { fn bar(arg: char) ${0:-> ()} {
${0:todo!()} todo!()
} }
"#, "#,
) )
@@ -548,8 +550,8 @@ fn foo() {
bar(42) bar(42)
} }
fn bar(arg: i32) { fn bar(arg: i32) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -569,8 +571,8 @@ fn foo() {
bar(42 as u8) bar(42 as u8)
} }
fn bar(arg: u8) { fn bar(arg: u8) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -594,8 +596,8 @@ fn foo() {
bar(x as u8) bar(x as u8)
} }
fn bar(x: u8) { fn bar(x: u8) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -617,8 +619,8 @@ fn foo() {
bar(worble) bar(worble)
} }
fn bar(worble: ()) { fn bar(worble: ()) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -646,8 +648,8 @@ fn baz() {
bar(foo()) bar(foo())
} }
fn bar(foo: impl Foo) { fn bar(foo: impl Foo) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -673,8 +675,8 @@ fn foo() {
bar(&baz()) bar(&baz())
} }
fn bar(baz: &Baz) { fn bar(baz: &Baz) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -702,8 +704,8 @@ fn foo() {
bar(Baz::baz()) bar(Baz::baz())
} }
fn bar(baz: Baz::Bof) { fn bar(baz: Baz::Bof) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -725,8 +727,8 @@ fn foo<T>(t: T) {
bar(t) bar(t)
} }
fn bar<T>(t: T) { fn bar<T>(t: T) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -756,8 +758,8 @@ fn foo() {
bar(Baz::new); bar(Baz::new);
} }
fn bar(arg: fn() -> Baz) { fn bar(arg: fn() -> Baz) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -781,8 +783,8 @@ fn foo() {
bar(closure) bar(closure)
} }
fn bar(closure: impl Fn(i64) -> i64) { fn bar(closure: impl Fn(i64) -> i64) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -802,8 +804,8 @@ fn foo() {
bar(baz) bar(baz)
} }
fn bar(baz: ()) { fn bar(baz: ()) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -827,8 +829,8 @@ fn foo() {
bar(baz(), baz()) bar(baz(), baz())
} }
fn bar(baz_1: Baz, baz_2: Baz) { fn bar(baz_1: Baz, baz_2: Baz) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -852,8 +854,8 @@ fn foo() {
bar(baz(), baz(), "foo", "bar") bar(baz(), baz(), "foo", "bar")
} }
fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) { fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) ${0:-> ()} {
${0:todo!()} todo!()
} }
"#, "#,
) )
@@ -872,8 +874,8 @@ fn foo() {
", ",
r" r"
mod bar { mod bar {
pub(crate) fn my_fn() { pub(crate) fn my_fn() ${0:-> ()} {
${0:todo!()} todo!()
} }
} }
@@ -911,8 +913,8 @@ fn bar() {
baz(foo) baz(foo)
} }
fn baz(foo: foo::Foo) { fn baz(foo: foo::Foo) ${0:-> ()} {
${0:todo!()} todo!()
} }
", ",
) )
@@ -935,8 +937,8 @@ fn foo() {
mod bar { mod bar {
fn something_else() {} fn something_else() {}
pub(crate) fn my_fn() { pub(crate) fn my_fn() ${0:-> ()} {
${0:todo!()} todo!()
} }
} }
@@ -963,8 +965,8 @@ fn foo() {
r" r"
mod bar { mod bar {
mod baz { mod baz {
pub(crate) fn my_fn() { pub(crate) fn my_fn() ${0:-> ()} {
${0:todo!()} todo!()
} }
} }
} }
@@ -992,8 +994,8 @@ fn main() {
r" r"
pub(crate) fn bar() { pub(crate) fn bar() ${0:-> ()} {
${0:todo!()} todo!()
}", }",
) )
} }

View File

@@ -454,8 +454,8 @@ fn foo() {
bar("", baz()); bar("", baz());
} }
fn bar(arg: &str, baz: Baz) { fn bar(arg: &str, baz: Baz) ${0:-> ()} {
${0:todo!()} todo!()
} }
"#####, "#####,

View File

@@ -320,6 +320,10 @@ pub fn param(name: String, ty: String) -> ast::Param {
ast_from_text(&format!("fn f({}: {}) {{ }}", name, ty)) ast_from_text(&format!("fn f({}: {}) {{ }}", name, ty))
} }
pub fn ret_type(ty: ast::Type) -> ast::RetType {
ast_from_text(&format!("fn f() -> {} {{ }}", ty))
}
pub fn param_list(pats: impl IntoIterator<Item = ast::Param>) -> ast::ParamList { pub fn param_list(pats: impl IntoIterator<Item = ast::Param>) -> ast::ParamList {
let args = pats.into_iter().join(", "); let args = pats.into_iter().join(", ");
ast_from_text(&format!("fn f({}) {{ }}", args)) ast_from_text(&format!("fn f({}) {{ }}", args))
@@ -350,14 +354,20 @@ pub fn fn_(
type_params: Option<ast::GenericParamList>, type_params: Option<ast::GenericParamList>,
params: ast::ParamList, params: ast::ParamList,
body: ast::BlockExpr, body: ast::BlockExpr,
ret_type: Option<ast::RetType>,
) -> ast::Fn { ) -> ast::Fn {
let type_params = let type_params =
if let Some(type_params) = type_params { format!("<{}>", type_params) } else { "".into() }; if let Some(type_params) = type_params { format!("<{}>", type_params) } else { "".into() };
let ret_type = if let Some(ret_type) = ret_type { format!("{} ", ret_type) } else { "".into() };
let visibility = match visibility { let visibility = match visibility {
None => String::new(), None => String::new(),
Some(it) => format!("{} ", it), Some(it) => format!("{} ", it),
}; };
ast_from_text(&format!("{}fn {}{}{} {}", visibility, fn_name, type_params, params, body))
ast_from_text(&format!(
"{}fn {}{}{} {}{}",
visibility, fn_name, type_params, params, ret_type, body
))
} }
fn ast_from_text<N: AstNode>(text: &str) -> N { fn ast_from_text<N: AstNode>(text: &str) -> N {