Add missing members generates indented blocks

This commit is contained in:
Aleksey Kladov 2020-05-02 11:50:43 +02:00
parent b58dfd24f1
commit b73dbbfbf2
4 changed files with 122 additions and 88 deletions

View file

@ -180,7 +180,9 @@ trait Trait<T> {
} }
impl Trait<u32> for () { impl Trait<u32> for () {
fn foo(&self) -> u32 { todo!() } fn foo(&self) -> u32 {
todo!()
}
} }
"#####, "#####,

View file

@ -1,6 +1,10 @@
use hir::HasSource; use hir::HasSource;
use ra_syntax::{ use ra_syntax::{
ast::{self, edit, make, AstNode, NameOwner}, ast::{
self,
edit::{self, IndentLevel},
make, AstNode, NameOwner,
},
SmolStr, SmolStr,
}; };
@ -40,7 +44,9 @@ enum AddMissingImplMembersMode {
// } // }
// //
// impl Trait<u32> for () { // impl Trait<u32> for () {
// fn foo(&self) -> u32 { todo!() } // fn foo(&self) -> u32 {
// todo!()
// }
// //
// } // }
// ``` // ```
@ -165,7 +171,9 @@ fn add_missing_impl_members_inner(
fn add_body(fn_def: ast::FnDef) -> ast::FnDef { fn add_body(fn_def: ast::FnDef) -> ast::FnDef {
if fn_def.body().is_none() { if fn_def.body().is_none() {
fn_def.with_body(make::block_from_expr(make::expr_todo())) let body = make::block_expr(None, Some(make::expr_todo()));
let body = IndentLevel(1).increase_indent(body);
fn_def.with_body(body)
} else { } else {
fn_def fn_def
} }
@ -181,7 +189,7 @@ mod tests {
fn test_add_missing_impl_members() { fn test_add_missing_impl_members() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
trait Foo { trait Foo {
type Output; type Output;
@ -197,8 +205,8 @@ struct S;
impl Foo for S { impl Foo for S {
fn bar(&self) {} fn bar(&self) {}
<|> <|>
}", }"#,
" r#"
trait Foo { trait Foo {
type Output; type Output;
@ -215,10 +223,14 @@ impl Foo for S {
fn bar(&self) {} fn bar(&self) {}
<|>type Output; <|>type Output;
const CONST: usize = 42; const CONST: usize = 42;
fn foo(&self) { todo!() } fn foo(&self) {
fn baz(&self) { todo!() } todo!()
}
fn baz(&self) {
todo!()
}
}", }"#,
); );
} }
@ -226,7 +238,7 @@ impl Foo for S {
fn test_copied_overriden_members() { fn test_copied_overriden_members() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
trait Foo { trait Foo {
fn foo(&self); fn foo(&self);
fn bar(&self) -> bool { true } fn bar(&self) -> bool { true }
@ -238,8 +250,8 @@ struct S;
impl Foo for S { impl Foo for S {
fn bar(&self) {} fn bar(&self) {}
<|> <|>
}", }"#,
" r#"
trait Foo { trait Foo {
fn foo(&self); fn foo(&self);
fn bar(&self) -> bool { true } fn bar(&self) -> bool { true }
@ -250,9 +262,11 @@ struct S;
impl Foo for S { impl Foo for S {
fn bar(&self) {} fn bar(&self) {}
<|>fn foo(&self) { todo!() } <|>fn foo(&self) {
todo!()
}
}", }"#,
); );
} }
@ -260,16 +274,18 @@ impl Foo for S {
fn test_empty_impl_def() { fn test_empty_impl_def() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
trait Foo { fn foo(&self); } trait Foo { fn foo(&self); }
struct S; struct S;
impl Foo for S { <|> }", impl Foo for S { <|> }"#,
" r#"
trait Foo { fn foo(&self); } trait Foo { fn foo(&self); }
struct S; struct S;
impl Foo for S { impl Foo for S {
<|>fn foo(&self) { todo!() } <|>fn foo(&self) {
}", todo!()
}
}"#,
); );
} }
@ -277,16 +293,18 @@ impl Foo for S {
fn fill_in_type_params_1() { fn fill_in_type_params_1() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
trait Foo<T> { fn foo(&self, t: T) -> &T; } trait Foo<T> { fn foo(&self, t: T) -> &T; }
struct S; struct S;
impl Foo<u32> for S { <|> }", impl Foo<u32> for S { <|> }"#,
" r#"
trait Foo<T> { fn foo(&self, t: T) -> &T; } trait Foo<T> { fn foo(&self, t: T) -> &T; }
struct S; struct S;
impl Foo<u32> for S { impl Foo<u32> for S {
<|>fn foo(&self, t: u32) -> &u32 { todo!() } <|>fn foo(&self, t: u32) -> &u32 {
}", todo!()
}
}"#,
); );
} }
@ -294,16 +312,18 @@ impl Foo<u32> for S {
fn fill_in_type_params_2() { fn fill_in_type_params_2() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
trait Foo<T> { fn foo(&self, t: T) -> &T; } trait Foo<T> { fn foo(&self, t: T) -> &T; }
struct S; struct S;
impl<U> Foo<U> for S { <|> }", impl<U> Foo<U> for S { <|> }"#,
" r#"
trait Foo<T> { fn foo(&self, t: T) -> &T; } trait Foo<T> { fn foo(&self, t: T) -> &T; }
struct S; struct S;
impl<U> Foo<U> for S { impl<U> Foo<U> for S {
<|>fn foo(&self, t: U) -> &U { todo!() } <|>fn foo(&self, t: U) -> &U {
}", todo!()
}
}"#,
); );
} }
@ -311,16 +331,18 @@ impl<U> Foo<U> for S {
fn test_cursor_after_empty_impl_def() { fn test_cursor_after_empty_impl_def() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
trait Foo { fn foo(&self); } trait Foo { fn foo(&self); }
struct S; struct S;
impl Foo for S {}<|>", impl Foo for S {}<|>"#,
" r#"
trait Foo { fn foo(&self); } trait Foo { fn foo(&self); }
struct S; struct S;
impl Foo for S { impl Foo for S {
<|>fn foo(&self) { todo!() } <|>fn foo(&self) {
}", todo!()
}
}"#,
) )
} }
@ -328,22 +350,24 @@ impl Foo for S {
fn test_qualify_path_1() { fn test_qualify_path_1() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
mod foo { mod foo {
pub struct Bar; pub struct Bar;
trait Foo { fn foo(&self, bar: Bar); } trait Foo { fn foo(&self, bar: Bar); }
} }
struct S; struct S;
impl foo::Foo for S { <|> }", impl foo::Foo for S { <|> }"#,
" r#"
mod foo { mod foo {
pub struct Bar; pub struct Bar;
trait Foo { fn foo(&self, bar: Bar); } trait Foo { fn foo(&self, bar: Bar); }
} }
struct S; struct S;
impl foo::Foo for S { impl foo::Foo for S {
<|>fn foo(&self, bar: foo::Bar) { todo!() } <|>fn foo(&self, bar: foo::Bar) {
}", todo!()
}
}"#,
); );
} }
@ -351,22 +375,24 @@ impl foo::Foo for S {
fn test_qualify_path_generic() { fn test_qualify_path_generic() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
mod foo { mod foo {
pub struct Bar<T>; pub struct Bar<T>;
trait Foo { fn foo(&self, bar: Bar<u32>); } trait Foo { fn foo(&self, bar: Bar<u32>); }
} }
struct S; struct S;
impl foo::Foo for S { <|> }", impl foo::Foo for S { <|> }"#,
" r#"
mod foo { mod foo {
pub struct Bar<T>; pub struct Bar<T>;
trait Foo { fn foo(&self, bar: Bar<u32>); } trait Foo { fn foo(&self, bar: Bar<u32>); }
} }
struct S; struct S;
impl foo::Foo for S { impl foo::Foo for S {
<|>fn foo(&self, bar: foo::Bar<u32>) { todo!() } <|>fn foo(&self, bar: foo::Bar<u32>) {
}", todo!()
}
}"#,
); );
} }
@ -374,22 +400,24 @@ impl foo::Foo for S {
fn test_qualify_path_and_substitute_param() { fn test_qualify_path_and_substitute_param() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
mod foo { mod foo {
pub struct Bar<T>; pub struct Bar<T>;
trait Foo<T> { fn foo(&self, bar: Bar<T>); } trait Foo<T> { fn foo(&self, bar: Bar<T>); }
} }
struct S; struct S;
impl foo::Foo<u32> for S { <|> }", impl foo::Foo<u32> for S { <|> }"#,
" r#"
mod foo { mod foo {
pub struct Bar<T>; pub struct Bar<T>;
trait Foo<T> { fn foo(&self, bar: Bar<T>); } trait Foo<T> { fn foo(&self, bar: Bar<T>); }
} }
struct S; struct S;
impl foo::Foo<u32> for S { impl foo::Foo<u32> for S {
<|>fn foo(&self, bar: foo::Bar<u32>) { todo!() } <|>fn foo(&self, bar: foo::Bar<u32>) {
}", todo!()
}
}"#,
); );
} }
@ -398,15 +426,15 @@ impl foo::Foo<u32> for S {
// when substituting params, the substituted param should not be qualified! // when substituting params, the substituted param should not be qualified!
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
mod foo { mod foo {
trait Foo<T> { fn foo(&self, bar: T); } trait Foo<T> { fn foo(&self, bar: T); }
pub struct Param; pub struct Param;
} }
struct Param; struct Param;
struct S; struct S;
impl foo::Foo<Param> for S { <|> }", impl foo::Foo<Param> for S { <|> }"#,
" r#"
mod foo { mod foo {
trait Foo<T> { fn foo(&self, bar: T); } trait Foo<T> { fn foo(&self, bar: T); }
pub struct Param; pub struct Param;
@ -414,8 +442,10 @@ mod foo {
struct Param; struct Param;
struct S; struct S;
impl foo::Foo<Param> for S { impl foo::Foo<Param> for S {
<|>fn foo(&self, bar: Param) { todo!() } <|>fn foo(&self, bar: Param) {
}", todo!()
}
}"#,
); );
} }
@ -423,15 +453,15 @@ impl foo::Foo<Param> for S {
fn test_qualify_path_associated_item() { fn test_qualify_path_associated_item() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
mod foo { mod foo {
pub struct Bar<T>; pub struct Bar<T>;
impl Bar<T> { type Assoc = u32; } impl Bar<T> { type Assoc = u32; }
trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); } trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); }
} }
struct S; struct S;
impl foo::Foo for S { <|> }", impl foo::Foo for S { <|> }"#,
" r#"
mod foo { mod foo {
pub struct Bar<T>; pub struct Bar<T>;
impl Bar<T> { type Assoc = u32; } impl Bar<T> { type Assoc = u32; }
@ -439,8 +469,10 @@ mod foo {
} }
struct S; struct S;
impl foo::Foo for S { impl foo::Foo for S {
<|>fn foo(&self, bar: foo::Bar<u32>::Assoc) { todo!() } <|>fn foo(&self, bar: foo::Bar<u32>::Assoc) {
}", todo!()
}
}"#,
); );
} }
@ -448,15 +480,15 @@ impl foo::Foo for S {
fn test_qualify_path_nested() { fn test_qualify_path_nested() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
mod foo { mod foo {
pub struct Bar<T>; pub struct Bar<T>;
pub struct Baz; pub struct Baz;
trait Foo { fn foo(&self, bar: Bar<Baz>); } trait Foo { fn foo(&self, bar: Bar<Baz>); }
} }
struct S; struct S;
impl foo::Foo for S { <|> }", impl foo::Foo for S { <|> }"#,
" r#"
mod foo { mod foo {
pub struct Bar<T>; pub struct Bar<T>;
pub struct Baz; pub struct Baz;
@ -464,8 +496,10 @@ mod foo {
} }
struct S; struct S;
impl foo::Foo for S { impl foo::Foo for S {
<|>fn foo(&self, bar: foo::Bar<foo::Baz>) { todo!() } <|>fn foo(&self, bar: foo::Bar<foo::Baz>) {
}", todo!()
}
}"#,
); );
} }
@ -473,22 +507,24 @@ impl foo::Foo for S {
fn test_qualify_path_fn_trait_notation() { fn test_qualify_path_fn_trait_notation() {
check_assist( check_assist(
add_missing_impl_members, add_missing_impl_members,
" r#"
mod foo { mod foo {
pub trait Fn<Args> { type Output; } pub trait Fn<Args> { type Output; }
trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
} }
struct S; struct S;
impl foo::Foo for S { <|> }", impl foo::Foo for S { <|> }"#,
" r#"
mod foo { mod foo {
pub trait Fn<Args> { type Output; } pub trait Fn<Args> { type Output; }
trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); }
} }
struct S; struct S;
impl foo::Foo for S { impl foo::Foo for S {
<|>fn foo(&self, bar: dyn Fn(u32) -> i32) { todo!() } <|>fn foo(&self, bar: dyn Fn(u32) -> i32) {
}", todo!()
}
}"#,
); );
} }
@ -496,10 +532,10 @@ impl foo::Foo for S {
fn test_empty_trait() { fn test_empty_trait() {
check_assist_not_applicable( check_assist_not_applicable(
add_missing_impl_members, add_missing_impl_members,
" r#"
trait Foo; trait Foo;
struct S; struct S;
impl Foo for S { <|> }", impl Foo for S { <|> }"#,
) )
} }
@ -507,13 +543,13 @@ impl Foo for S { <|> }",
fn test_ignore_unnamed_trait_members_and_default_methods() { fn test_ignore_unnamed_trait_members_and_default_methods() {
check_assist_not_applicable( check_assist_not_applicable(
add_missing_impl_members, add_missing_impl_members,
" r#"
trait Foo { trait Foo {
fn (arg: u32); fn (arg: u32);
fn valid(some: u32) -> bool { false } fn valid(some: u32) -> bool { false }
} }
struct S; struct S;
impl Foo for S { <|> }", impl Foo for S { <|> }"#,
) )
} }
@ -544,7 +580,9 @@ trait Foo {
struct S; struct S;
impl Foo for S { impl Foo for S {
<|>type Output; <|>type Output;
fn foo(&self) { todo!() } fn foo(&self) {
todo!()
}
}"#, }"#,
) )
} }
@ -553,7 +591,7 @@ impl Foo for S {
fn test_default_methods() { fn test_default_methods() {
check_assist( check_assist(
add_missing_default_members, add_missing_default_members,
" r#"
trait Foo { trait Foo {
type Output; type Output;
@ -563,8 +601,8 @@ trait Foo {
fn foo(some: u32) -> bool; fn foo(some: u32) -> bool;
} }
struct S; struct S;
impl Foo for S { <|> }", impl Foo for S { <|> }"#,
" r#"
trait Foo { trait Foo {
type Output; type Output;
@ -576,7 +614,7 @@ trait Foo {
struct S; struct S;
impl Foo for S { impl Foo for S {
<|>fn valid(some: u32) -> bool { false } <|>fn valid(some: u32) -> bool { false }
}", }"#,
) )
} }
} }

View file

@ -82,14 +82,6 @@ pub fn block_expr(
ast_from_text(&format!("fn f() {}", buf)) ast_from_text(&format!("fn f() {}", buf))
} }
pub fn block_from_expr(e: ast::Expr) -> ast::BlockExpr {
return from_text(&format!("{{ {} }}", e));
fn from_text(text: &str) -> ast::BlockExpr {
ast_from_text(&format!("fn f() {}", text))
}
}
pub fn expr_unit() -> ast::Expr { pub fn expr_unit() -> ast::Expr {
expr_from_text("()") expr_from_text("()")
} }

View file

@ -175,7 +175,9 @@ trait Trait<T> {
} }
impl Trait<u32> for () { impl Trait<u32> for () {
fn foo(&self) -> u32 { todo!() } fn foo(&self) -> u32 {
todo!()
}
} }
``` ```