From 5b0b87f8deded258585d161c3077280e7d8112e9 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Sat, 16 Mar 2019 23:19:14 +0100 Subject: Provide assist when cursor is immediately outside impl item block --- crates/ra_assists/src/add_missing_impl_members.rs | 32 +++++++++++++---------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'crates/ra_assists') diff --git a/crates/ra_assists/src/add_missing_impl_members.rs b/crates/ra_assists/src/add_missing_impl_members.rs index 567fc9586..96dde3c4b 100644 --- a/crates/ra_assists/src/add_missing_impl_members.rs +++ b/crates/ra_assists/src/add_missing_impl_members.rs @@ -11,7 +11,7 @@ use itertools::Itertools; /// Given an `ast::ImplBlock`, resolves the target trait (the one being /// implemented) to a `ast::TraitDef`. -pub(crate) fn resolve_target_trait_def( +fn resolve_target_trait_def( db: &impl HirDatabase, resolver: &Resolver, impl_block: &ast::ImplBlock, @@ -25,7 +25,7 @@ pub(crate) fn resolve_target_trait_def( } } -pub(crate) fn build_func_body(def: &ast::FnDef) -> String { +fn build_func_body(def: &ast::FnDef) -> String { let mut buf = String::new(); for child in def.syntax().children() { @@ -40,17 +40,12 @@ pub(crate) fn build_func_body(def: &ast::FnDef) -> String { } pub(crate) fn add_missing_impl_members(mut ctx: AssistCtx) -> Option { - let node = ctx.covering_node(); - let impl_node = node.ancestors().find_map(ast::ImplBlock::cast)?; + let impl_node = ctx.node_at_offset::()?; let impl_item_list = impl_node.item_list()?; - // Don't offer the assist when cursor is at the end, outside the block itself. - let cursor_range = TextRange::from_to(node.range().end(), node.range().end()); - if node.range().end() == impl_node.syntax().range().end() { - return None; - } let trait_def = { - let position = FilePosition { file_id: ctx.frange.file_id, offset: cursor_range.end() }; + let file_id = ctx.frange.file_id; + let position = FilePosition { file_id, offset: impl_node.syntax().range().start() }; let resolver = hir::source_binder::resolver_for_position(ctx.db, position); resolve_target_trait_def(ctx.db, &resolver, impl_node)? @@ -94,10 +89,13 @@ pub(crate) fn add_missing_impl_members(mut ctx: AssistCtx) -> }; let changed_range = { - let last_whitespace = impl_item_list.syntax().children(); - let last_whitespace = last_whitespace.filter_map(ast::Whitespace::cast).last(); + let children = impl_item_list.syntax().children(); + let last_whitespace = children.filter_map(ast::Whitespace::cast).last(); - last_whitespace.map(|w| w.syntax().range()).unwrap_or(cursor_range) + last_whitespace.map(|w| w.syntax().range()).unwrap_or_else(|| { + let in_brackets = impl_item_list.syntax().range().end() - TextUnit::of_str("}"); + TextRange::from_to(in_brackets, in_brackets) + }) }; let func_bodies = format!("\n{}", missing_fns.into_iter().map(build_func_body).join("\n")); @@ -207,12 +205,18 @@ impl Foo for S { #[test] fn test_cursor_after_empty_impl_block() { - check_assist_not_applicable( + check_assist( add_missing_impl_members, " trait Foo { fn foo(&self); } struct S; impl Foo for S {}<|>", + " +trait Foo { fn foo(&self); } +struct S; +impl Foo for S { + fn foo(&self) { unimplemented!() }<|> +}", ) } -- cgit v1.2.3