aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists/src/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_assists/src/handlers')
-rw-r--r--crates/ide_assists/src/handlers/extract_function.rs35
-rw-r--r--crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs2
-rw-r--r--crates/ide_assists/src/handlers/reorder_impl.rs40
3 files changed, 61 insertions, 16 deletions
diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs
index 5f80a40c8..93b28370c 100644
--- a/crates/ide_assists/src/handlers/extract_function.rs
+++ b/crates/ide_assists/src/handlers/extract_function.rs
@@ -16,12 +16,13 @@ use syntax::{
16 edit::{AstNodeEdit, IndentLevel}, 16 edit::{AstNodeEdit, IndentLevel},
17 AstNode, 17 AstNode,
18 }, 18 },
19 ted,
19 SyntaxKind::{self, BLOCK_EXPR, BREAK_EXPR, COMMENT, PATH_EXPR, RETURN_EXPR}, 20 SyntaxKind::{self, BLOCK_EXPR, BREAK_EXPR, COMMENT, PATH_EXPR, RETURN_EXPR},
20 SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset, WalkEvent, T, 21 SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset, WalkEvent, T,
21}; 22};
22 23
23use crate::{ 24use crate::{
24 assist_context::{AssistContext, Assists}, 25 assist_context::{AssistContext, Assists, TreeMutator},
25 AssistId, 26 AssistId,
26}; 27};
27 28
@@ -1183,7 +1184,7 @@ fn make_ret_ty(ctx: &AssistContext, module: hir::Module, fun: &Function) -> Opti
1183 } 1184 }
1184 FlowHandler::Try { kind: TryKind::Result { ty: parent_ret_ty } } => { 1185 FlowHandler::Try { kind: TryKind::Result { ty: parent_ret_ty } } => {
1185 let handler_ty = parent_ret_ty 1186 let handler_ty = parent_ret_ty
1186 .type_parameters() 1187 .type_arguments()
1187 .nth(1) 1188 .nth(1)
1188 .map(|ty| make_ty(&ty, ctx, module)) 1189 .map(|ty| make_ty(&ty, ctx, module))
1189 .unwrap_or_else(make::ty_unit); 1190 .unwrap_or_else(make::ty_unit);
@@ -1366,7 +1367,10 @@ fn rewrite_body_segment(
1366 1367
1367/// change all usages to account for added `&`/`&mut` for some params 1368/// change all usages to account for added `&`/`&mut` for some params
1368fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode) -> SyntaxNode { 1369fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode) -> SyntaxNode {
1369 let mut rewriter = SyntaxRewriter::default(); 1370 let mut usages_for_param: Vec<(&Param, Vec<ast::Expr>)> = Vec::new();
1371
1372 let tm = TreeMutator::new(syntax);
1373
1370 for param in params { 1374 for param in params {
1371 if !param.kind().is_ref() { 1375 if !param.kind().is_ref() {
1372 continue; 1376 continue;
@@ -1376,30 +1380,39 @@ fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode)
1376 let usages = usages 1380 let usages = usages
1377 .iter() 1381 .iter()
1378 .filter(|reference| syntax.text_range().contains_range(reference.range)) 1382 .filter(|reference| syntax.text_range().contains_range(reference.range))
1379 .filter_map(|reference| path_element_of_reference(syntax, reference)); 1383 .filter_map(|reference| path_element_of_reference(syntax, reference))
1380 for path in usages { 1384 .map(|expr| tm.make_mut(&expr));
1381 match path.syntax().ancestors().skip(1).find_map(ast::Expr::cast) { 1385
1386 usages_for_param.push((param, usages.collect()));
1387 }
1388
1389 let res = tm.make_syntax_mut(syntax);
1390
1391 for (param, usages) in usages_for_param {
1392 for usage in usages {
1393 match usage.syntax().ancestors().skip(1).find_map(ast::Expr::cast) {
1382 Some(ast::Expr::MethodCallExpr(_)) | Some(ast::Expr::FieldExpr(_)) => { 1394 Some(ast::Expr::MethodCallExpr(_)) | Some(ast::Expr::FieldExpr(_)) => {
1383 // do nothing 1395 // do nothing
1384 } 1396 }
1385 Some(ast::Expr::RefExpr(node)) 1397 Some(ast::Expr::RefExpr(node))
1386 if param.kind() == ParamKind::MutRef && node.mut_token().is_some() => 1398 if param.kind() == ParamKind::MutRef && node.mut_token().is_some() =>
1387 { 1399 {
1388 rewriter.replace_ast(&node.clone().into(), &node.expr().unwrap()); 1400 ted::replace(node.syntax(), node.expr().unwrap().syntax());
1389 } 1401 }
1390 Some(ast::Expr::RefExpr(node)) 1402 Some(ast::Expr::RefExpr(node))
1391 if param.kind() == ParamKind::SharedRef && node.mut_token().is_none() => 1403 if param.kind() == ParamKind::SharedRef && node.mut_token().is_none() =>
1392 { 1404 {
1393 rewriter.replace_ast(&node.clone().into(), &node.expr().unwrap()); 1405 ted::replace(node.syntax(), node.expr().unwrap().syntax());
1394 } 1406 }
1395 Some(_) | None => { 1407 Some(_) | None => {
1396 rewriter.replace_ast(&path, &make::expr_prefix(T![*], path.clone())); 1408 let p = &make::expr_prefix(T![*], usage.clone()).clone_for_update();
1409 ted::replace(usage.syntax(), p.syntax())
1397 } 1410 }
1398 }; 1411 }
1399 } 1412 }
1400 } 1413 }
1401 1414
1402 rewriter.rewrite(syntax) 1415 res
1403} 1416}
1404 1417
1405fn update_external_control_flow(handler: &FlowHandler, syntax: &SyntaxNode) -> SyntaxNode { 1418fn update_external_control_flow(handler: &FlowHandler, syntax: &SyntaxNode) -> SyntaxNode {
diff --git a/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs b/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs
index c13c6eebe..ce6998d82 100644
--- a/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs
+++ b/crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs
@@ -91,7 +91,7 @@ fn existing_from_impl(
91 91
92 let enum_type = enum_.ty(sema.db); 92 let enum_type = enum_.ty(sema.db);
93 93
94 let wrapped_type = variant.fields(sema.db).get(0)?.signature_ty(sema.db); 94 let wrapped_type = variant.fields(sema.db).get(0)?.ty(sema.db);
95 95
96 if enum_type.impls_trait(sema.db, from_trait, &[wrapped_type]) { 96 if enum_type.impls_trait(sema.db, from_trait, &[wrapped_type]) {
97 Some(()) 97 Some(())
diff --git a/crates/ide_assists/src/handlers/reorder_impl.rs b/crates/ide_assists/src/handlers/reorder_impl.rs
index 72d889248..54a9a468e 100644
--- a/crates/ide_assists/src/handlers/reorder_impl.rs
+++ b/crates/ide_assists/src/handlers/reorder_impl.rs
@@ -79,9 +79,12 @@ pub(crate) fn reorder_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
79 "Sort methods", 79 "Sort methods",
80 target, 80 target,
81 |builder| { 81 |builder| {
82 methods.into_iter().zip(sorted).for_each(|(old, new)| { 82 let methods =
83 ted::replace(builder.make_ast_mut(old).syntax(), new.clone_for_update().syntax()) 83 methods.into_iter().map(|fn_| builder.make_ast_mut(fn_)).collect::<Vec<_>>();
84 }); 84 methods
85 .into_iter()
86 .zip(sorted)
87 .for_each(|(old, new)| ted::replace(old.syntax(), new.clone_for_update().syntax()));
85 }, 88 },
86 ) 89 )
87} 90}
@@ -160,7 +163,7 @@ $0impl Bar for Foo {}
160 } 163 }
161 164
162 #[test] 165 #[test]
163 fn reorder_impl_trait_methods() { 166 fn reorder_impl_trait_functions() {
164 check_assist( 167 check_assist(
165 reorder_impl, 168 reorder_impl,
166 r#" 169 r#"
@@ -197,4 +200,33 @@ impl Bar for Foo {
197 "#, 200 "#,
198 ) 201 )
199 } 202 }
203
204 #[test]
205 fn reorder_impl_trait_methods_uneven_ident_lengths() {
206 check_assist(
207 reorder_impl,
208 r#"
209trait Bar {
210 fn foo(&mut self) {}
211 fn fooo(&mut self) {}
212}
213
214struct Foo;
215impl Bar for Foo {
216 fn fooo(&mut self) {}
217 fn foo(&mut self) {$0}
218}"#,
219 r#"
220trait Bar {
221 fn foo(&mut self) {}
222 fn fooo(&mut self) {}
223}
224
225struct Foo;
226impl Bar for Foo {
227 fn foo(&mut self) {}
228 fn fooo(&mut self) {}
229}"#,
230 )
231 }
200} 232}