aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists/src/handlers')
-rw-r--r--crates/assists/src/handlers/add_missing_impl_members.rs75
-rw-r--r--crates/assists/src/handlers/auto_import.rs33
-rw-r--r--crates/assists/src/handlers/invert_if.rs13
-rw-r--r--crates/assists/src/handlers/merge_imports.rs14
-rw-r--r--crates/assists/src/handlers/replace_qualified_name_with_use.rs20
5 files changed, 119 insertions, 36 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#"
321trait Foo { fn foo(&self); }
322struct S;
323impl Foo for S<|>"#,
324 r#"
325trait Foo { fn foo(&self); }
326struct S;
327impl 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#"
422mod foo {
423 pub mod bar {
424 pub struct Bar;
425 pub trait Foo { fn foo(&self, bar: Bar); }
426 }
427}
428
429use foo::bar;
430
431struct S;
432impl bar::Foo for S { <|> }"#,
433 r#"
434mod foo {
435 pub mod bar {
436 pub struct Bar;
437 pub trait Foo { fn foo(&self, bar: Bar); }
438 }
439}
440
441use foo::bar;
442
443struct S;
444impl 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 5a1b5a4ac..fa524ffd9 100644
--- a/crates/assists/src/handlers/auto_import.rs
+++ b/crates/assists/src/handlers/auto_import.rs
@@ -192,10 +192,10 @@ impl AutoImportAssets {
192 }) 192 })
193 .filter_map(|candidate| match candidate { 193 .filter_map(|candidate| match candidate {
194 Either::Left(module_def) => { 194 Either::Left(module_def) => {
195 self.module_with_name_to_import.find_use_path(db, module_def) 195 self.module_with_name_to_import.find_use_path_prefixed(db, module_def)
196 } 196 }
197 Either::Right(macro_def) => { 197 Either::Right(macro_def) => {
198 self.module_with_name_to_import.find_use_path(db, macro_def) 198 self.module_with_name_to_import.find_use_path_prefixed(db, macro_def)
199 } 199 }
200 }) 200 })
201 .filter(|use_path| !use_path.segments.is_empty()) 201 .filter(|use_path| !use_path.segments.is_empty())
@@ -287,6 +287,35 @@ mod tests {
287 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; 287 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
288 288
289 #[test] 289 #[test]
290 fn applicable_when_found_an_import_partial() {
291 check_assist(
292 auto_import,
293 r"
294 mod std {
295 pub mod fmt {
296 pub struct Formatter;
297 }
298 }
299
300 use std::fmt;
301
302 <|>Formatter
303 ",
304 r"
305 mod std {
306 pub mod fmt {
307 pub struct Formatter;
308 }
309 }
310
311 use std::fmt::{self, Formatter};
312
313 Formatter
314 ",
315 );
316 }
317
318 #[test]
290 fn applicable_when_found_an_import() { 319 fn applicable_when_found_an_import() {
291 check_assist( 320 check_assist(
292 auto_import, 321 auto_import,
diff --git a/crates/assists/src/handlers/invert_if.rs b/crates/assists/src/handlers/invert_if.rs
index 294256297..461fcf862 100644
--- a/crates/assists/src/handlers/invert_if.rs
+++ b/crates/assists/src/handlers/invert_if.rs
@@ -49,13 +49,14 @@ pub(crate) fn invert_if(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
49 ast::ElseBranch::IfExpr(_) => return None, 49 ast::ElseBranch::IfExpr(_) => return None,
50 }; 50 };
51 51
52 let cond_range = cond.syntax().text_range();
53 let flip_cond = invert_boolean_expression(cond);
54 let else_node = else_block.syntax();
55 let else_range = else_node.text_range();
56 let then_range = then_node.text_range();
57 acc.add(AssistId("invert_if", AssistKind::RefactorRewrite), "Invert if", if_range, |edit| { 52 acc.add(AssistId("invert_if", AssistKind::RefactorRewrite), "Invert if", if_range, |edit| {
58 edit.replace(cond_range, flip_cond.syntax().text()); 53 let flip_cond = invert_boolean_expression(cond.clone());
54 edit.replace_ast(cond, flip_cond);
55
56 let else_node = else_block.syntax();
57 let else_range = else_node.text_range();
58 let then_range = then_node.text_range();
59
59 edit.replace(else_range, then_node.text()); 60 edit.replace(else_range, then_node.text());
60 edit.replace(then_range, else_node.text()); 61 edit.replace(then_range, else_node.text());
61 }) 62 })
diff --git a/crates/assists/src/handlers/merge_imports.rs b/crates/assists/src/handlers/merge_imports.rs
index 0bd679260..fe33cee53 100644
--- a/crates/assists/src/handlers/merge_imports.rs
+++ b/crates/assists/src/handlers/merge_imports.rs
@@ -95,7 +95,7 @@ use std::fmt::Debug;
95use std::fmt<|>::Display; 95use std::fmt<|>::Display;
96", 96",
97 r" 97 r"
98use std::fmt::{Display, Debug}; 98use std::fmt::{Debug, Display};
99", 99",
100 ); 100 );
101 } 101 }
@@ -122,7 +122,7 @@ use std::fmt::{self, Display};
122use std::{fmt, <|>fmt::Display}; 122use std::{fmt, <|>fmt::Display};
123", 123",
124 r" 124 r"
125use std::{fmt::{Display, self}}; 125use std::{fmt::{self, Display}};
126", 126",
127 ); 127 );
128 } 128 }
@@ -210,13 +210,17 @@ use std::{fmt<|>::Debug, fmt::Display};
210use std::{fmt::{Debug, Display}}; 210use std::{fmt::{Debug, Display}};
211", 211",
212 ); 212 );
213 }
214
215 #[test]
216 fn test_merge_nested2() {
213 check_assist( 217 check_assist(
214 merge_imports, 218 merge_imports,
215 r" 219 r"
216use std::{fmt::Debug, fmt<|>::Display}; 220use std::{fmt::Debug, fmt<|>::Display};
217", 221",
218 r" 222 r"
219use std::{fmt::{Display, Debug}}; 223use std::{fmt::{Debug, Display}};
220", 224",
221 ); 225 );
222 } 226 }
@@ -310,9 +314,7 @@ use foo::<|>{
310}; 314};
311", 315",
312 r" 316 r"
313use foo::{ 317use foo::{FooBar, bar::baz};
314 FooBar,
315bar::baz};
316", 318",
317 ) 319 )
318 } 320 }
diff --git a/crates/assists/src/handlers/replace_qualified_name_with_use.rs b/crates/assists/src/handlers/replace_qualified_name_with_use.rs
index 27b49455c..74afc123b 100644
--- a/crates/assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/assists/src/handlers/replace_qualified_name_with_use.rs
@@ -298,7 +298,7 @@ impl std::fmt<|> for Foo {
298} 298}
299 ", 299 ",
300 r" 300 r"
301use std::fmt::{Debug, self}; 301use std::fmt::{self, Debug};
302 302
303impl fmt for Foo { 303impl fmt for Foo {
304} 304}
@@ -316,9 +316,8 @@ use std::fmt::{Debug, nested::{Display}};
316impl std::fmt::nested<|> for Foo { 316impl std::fmt::nested<|> for Foo {
317} 317}
318", 318",
319 // FIXME(veykril): should be nested::{self, Display} here
320 r" 319 r"
321use std::fmt::{Debug, nested::{Display}, nested}; 320use std::fmt::{Debug, nested::{self, Display}};
322 321
323impl nested for Foo { 322impl nested for Foo {
324} 323}
@@ -336,9 +335,8 @@ use std::fmt::{Debug, nested::{self, Display}};
336impl std::fmt::nested<|> for Foo { 335impl std::fmt::nested<|> for Foo {
337} 336}
338", 337",
339 // FIXME(veykril): nested is duplicated now
340 r" 338 r"
341use std::fmt::{Debug, nested::{self, Display}, nested}; 339use std::fmt::{Debug, nested::{self, Display}};
342 340
343impl nested for Foo { 341impl nested for Foo {
344} 342}
@@ -357,7 +355,7 @@ impl std::fmt::nested::Debug<|> for Foo {
357} 355}
358", 356",
359 r" 357 r"
360use std::fmt::{Debug, nested::{Display}, nested::Debug}; 358use std::fmt::{Debug, nested::{Debug, Display}};
361 359
362impl Debug for Foo { 360impl Debug for Foo {
363} 361}
@@ -395,7 +393,7 @@ impl std::fmt::Display<|> for Foo {
395} 393}
396", 394",
397 r" 395 r"
398use std::fmt::{nested::Debug, Display}; 396use std::fmt::{Display, nested::Debug};
399 397
400impl Display for Foo { 398impl Display for Foo {
401} 399}
@@ -415,12 +413,8 @@ use crate::{
415 413
416fn foo() { crate::ty::lower<|>::trait_env() } 414fn foo() { crate::ty::lower<|>::trait_env() }
417", 415",
418 // FIXME(veykril): formatting broke here
419 r" 416 r"
420use crate::{ 417use crate::{AssocItem, ty::{Substs, Ty, lower}};
421 ty::{Substs, Ty},
422 AssocItem,
423ty::lower};
424 418
425fn foo() { lower::trait_env() } 419fn foo() { lower::trait_env() }
426", 420",
@@ -619,7 +613,7 @@ fn main() {
619} 613}
620 ", 614 ",
621 r" 615 r"
622use std::fmt::{Display, self}; 616use std::fmt::{self, Display};
623 617
624fn main() { 618fn main() {
625 fmt; 619 fmt;