diff options
Diffstat (limited to 'crates/assists/src/handlers')
-rw-r--r-- | crates/assists/src/handlers/add_missing_impl_members.rs | 75 | ||||
-rw-r--r-- | crates/assists/src/handlers/auto_import.rs | 33 |
2 files changed, 97 insertions, 11 deletions
diff --git a/crates/assists/src/handlers/add_missing_impl_members.rs b/crates/assists/src/handlers/add_missing_impl_members.rs index 83a2ada9a..1ac5fefd6 100644 --- a/crates/assists/src/handlers/add_missing_impl_members.rs +++ b/crates/assists/src/handlers/add_missing_impl_members.rs | |||
@@ -111,8 +111,6 @@ fn add_missing_impl_members_inner( | |||
111 | ) -> Option<()> { | 111 | ) -> Option<()> { |
112 | let _p = profile::span("add_missing_impl_members_inner"); | 112 | let _p = profile::span("add_missing_impl_members_inner"); |
113 | let impl_def = ctx.find_node_at_offset::<ast::Impl>()?; | 113 | let impl_def = ctx.find_node_at_offset::<ast::Impl>()?; |
114 | let impl_item_list = impl_def.assoc_item_list()?; | ||
115 | |||
116 | let trait_ = resolve_target_trait(&ctx.sema, &impl_def)?; | 114 | let trait_ = resolve_target_trait(&ctx.sema, &impl_def)?; |
117 | 115 | ||
118 | let def_name = |item: &ast::AssocItem| -> Option<SmolStr> { | 116 | let def_name = |item: &ast::AssocItem| -> Option<SmolStr> { |
@@ -148,11 +146,14 @@ fn add_missing_impl_members_inner( | |||
148 | 146 | ||
149 | let target = impl_def.syntax().text_range(); | 147 | let target = impl_def.syntax().text_range(); |
150 | acc.add(AssistId(assist_id, AssistKind::QuickFix), label, target, |builder| { | 148 | acc.add(AssistId(assist_id, AssistKind::QuickFix), label, target, |builder| { |
149 | let impl_item_list = impl_def.assoc_item_list().unwrap_or(make::assoc_item_list()); | ||
150 | |||
151 | let n_existing_items = impl_item_list.assoc_items().count(); | 151 | let n_existing_items = impl_item_list.assoc_items().count(); |
152 | let source_scope = ctx.sema.scope_for_def(trait_); | 152 | let source_scope = ctx.sema.scope_for_def(trait_); |
153 | let target_scope = ctx.sema.scope(impl_item_list.syntax()); | 153 | let target_scope = ctx.sema.scope(impl_def.syntax()); |
154 | let ast_transform = QualifyPaths::new(&target_scope, &source_scope) | 154 | let ast_transform = QualifyPaths::new(&target_scope, &source_scope) |
155 | .or(SubstituteTypeParams::for_trait_impl(&source_scope, trait_, impl_def)); | 155 | .or(SubstituteTypeParams::for_trait_impl(&source_scope, trait_, impl_def.clone())); |
156 | |||
156 | let items = missing_items | 157 | let items = missing_items |
157 | .into_iter() | 158 | .into_iter() |
158 | .map(|it| ast_transform::apply(&*ast_transform, it)) | 159 | .map(|it| ast_transform::apply(&*ast_transform, it)) |
@@ -162,12 +163,14 @@ fn add_missing_impl_members_inner( | |||
162 | _ => it, | 163 | _ => it, |
163 | }) | 164 | }) |
164 | .map(|it| edit::remove_attrs_and_docs(&it)); | 165 | .map(|it| edit::remove_attrs_and_docs(&it)); |
166 | |||
165 | let new_impl_item_list = impl_item_list.append_items(items); | 167 | let new_impl_item_list = impl_item_list.append_items(items); |
166 | let first_new_item = new_impl_item_list.assoc_items().nth(n_existing_items).unwrap(); | 168 | let new_impl_def = impl_def.with_assoc_item_list(new_impl_item_list); |
169 | let first_new_item = | ||
170 | new_impl_def.assoc_item_list().unwrap().assoc_items().nth(n_existing_items).unwrap(); | ||
167 | 171 | ||
168 | let original_range = impl_item_list.syntax().text_range(); | ||
169 | match ctx.config.snippet_cap { | 172 | match ctx.config.snippet_cap { |
170 | None => builder.replace(original_range, new_impl_item_list.to_string()), | 173 | None => builder.replace(target, new_impl_def.to_string()), |
171 | Some(cap) => { | 174 | Some(cap) => { |
172 | let mut cursor = Cursor::Before(first_new_item.syntax()); | 175 | let mut cursor = Cursor::Before(first_new_item.syntax()); |
173 | let placeholder; | 176 | let placeholder; |
@@ -181,8 +184,8 @@ fn add_missing_impl_members_inner( | |||
181 | } | 184 | } |
182 | builder.replace_snippet( | 185 | builder.replace_snippet( |
183 | cap, | 186 | cap, |
184 | original_range, | 187 | target, |
185 | render_snippet(cap, new_impl_item_list.syntax(), cursor), | 188 | render_snippet(cap, new_impl_def.syntax(), cursor), |
186 | ) | 189 | ) |
187 | } | 190 | } |
188 | }; | 191 | }; |
@@ -311,6 +314,25 @@ impl Foo for S { | |||
311 | } | 314 | } |
312 | 315 | ||
313 | #[test] | 316 | #[test] |
317 | fn test_impl_def_without_braces() { | ||
318 | check_assist( | ||
319 | add_missing_impl_members, | ||
320 | r#" | ||
321 | trait Foo { fn foo(&self); } | ||
322 | struct S; | ||
323 | impl Foo for S<|>"#, | ||
324 | r#" | ||
325 | trait Foo { fn foo(&self); } | ||
326 | struct S; | ||
327 | impl Foo for S { | ||
328 | fn foo(&self) { | ||
329 | ${0:todo!()} | ||
330 | } | ||
331 | }"#, | ||
332 | ); | ||
333 | } | ||
334 | |||
335 | #[test] | ||
314 | fn fill_in_type_params_1() { | 336 | fn fill_in_type_params_1() { |
315 | check_assist( | 337 | check_assist( |
316 | add_missing_impl_members, | 338 | add_missing_impl_members, |
@@ -393,6 +415,41 @@ impl foo::Foo for S { | |||
393 | } | 415 | } |
394 | 416 | ||
395 | #[test] | 417 | #[test] |
418 | fn test_qualify_path_2() { | ||
419 | check_assist( | ||
420 | add_missing_impl_members, | ||
421 | r#" | ||
422 | mod foo { | ||
423 | pub mod bar { | ||
424 | pub struct Bar; | ||
425 | pub trait Foo { fn foo(&self, bar: Bar); } | ||
426 | } | ||
427 | } | ||
428 | |||
429 | use foo::bar; | ||
430 | |||
431 | struct S; | ||
432 | impl bar::Foo for S { <|> }"#, | ||
433 | r#" | ||
434 | mod foo { | ||
435 | pub mod bar { | ||
436 | pub struct Bar; | ||
437 | pub trait Foo { fn foo(&self, bar: Bar); } | ||
438 | } | ||
439 | } | ||
440 | |||
441 | use foo::bar; | ||
442 | |||
443 | struct S; | ||
444 | impl bar::Foo for S { | ||
445 | fn foo(&self, bar: bar::Bar) { | ||
446 | ${0:todo!()} | ||
447 | } | ||
448 | }"#, | ||
449 | ); | ||
450 | } | ||
451 | |||
452 | #[test] | ||
396 | fn test_qualify_path_generic() { | 453 | fn test_qualify_path_generic() { |
397 | check_assist( | 454 | check_assist( |
398 | add_missing_impl_members, | 455 | add_missing_impl_members, |
diff --git a/crates/assists/src/handlers/auto_import.rs b/crates/assists/src/handlers/auto_import.rs index b5eb2c722..ee7277c04 100644 --- a/crates/assists/src/handlers/auto_import.rs +++ b/crates/assists/src/handlers/auto_import.rs | |||
@@ -196,10 +196,10 @@ impl AutoImportAssets { | |||
196 | }) | 196 | }) |
197 | .filter_map(|candidate| match candidate { | 197 | .filter_map(|candidate| match candidate { |
198 | Either::Left(module_def) => { | 198 | Either::Left(module_def) => { |
199 | self.module_with_name_to_import.find_use_path(db, module_def) | 199 | self.module_with_name_to_import.find_use_path_prefixed(db, module_def) |
200 | } | 200 | } |
201 | Either::Right(macro_def) => { | 201 | Either::Right(macro_def) => { |
202 | self.module_with_name_to_import.find_use_path(db, macro_def) | 202 | self.module_with_name_to_import.find_use_path_prefixed(db, macro_def) |
203 | } | 203 | } |
204 | }) | 204 | }) |
205 | .filter(|use_path| !use_path.segments.is_empty()) | 205 | .filter(|use_path| !use_path.segments.is_empty()) |
@@ -291,6 +291,35 @@ mod tests { | |||
291 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; | 291 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; |
292 | 292 | ||
293 | #[test] | 293 | #[test] |
294 | fn applicable_when_found_an_import_partial() { | ||
295 | check_assist( | ||
296 | auto_import, | ||
297 | r" | ||
298 | mod std { | ||
299 | pub mod fmt { | ||
300 | pub struct Formatter; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | use std::fmt; | ||
305 | |||
306 | <|>Formatter | ||
307 | ", | ||
308 | r" | ||
309 | mod std { | ||
310 | pub mod fmt { | ||
311 | pub struct Formatter; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | use std::fmt::{self, Formatter}; | ||
316 | |||
317 | Formatter | ||
318 | ", | ||
319 | ); | ||
320 | } | ||
321 | |||
322 | #[test] | ||
294 | fn applicable_when_found_an_import() { | 323 | fn applicable_when_found_an_import() { |
295 | check_assist( | 324 | check_assist( |
296 | auto_import, | 325 | auto_import, |