diff options
Diffstat (limited to 'crates/ide_assists/src/handlers')
-rw-r--r-- | crates/ide_assists/src/handlers/extract_function.rs | 35 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/generate_from_impl_for_enum.rs | 2 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/reorder_impl.rs | 40 |
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 | ||
23 | use crate::{ | 24 | use 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 |
1368 | fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode) -> SyntaxNode { | 1369 | fn 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 | ||
1405 | fn update_external_control_flow(handler: &FlowHandler, syntax: &SyntaxNode) -> SyntaxNode { | 1418 | fn 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#" | ||
209 | trait Bar { | ||
210 | fn foo(&mut self) {} | ||
211 | fn fooo(&mut self) {} | ||
212 | } | ||
213 | |||
214 | struct Foo; | ||
215 | impl Bar for Foo { | ||
216 | fn fooo(&mut self) {} | ||
217 | fn foo(&mut self) {$0} | ||
218 | }"#, | ||
219 | r#" | ||
220 | trait Bar { | ||
221 | fn foo(&mut self) {} | ||
222 | fn fooo(&mut self) {} | ||
223 | } | ||
224 | |||
225 | struct Foo; | ||
226 | impl Bar for Foo { | ||
227 | fn foo(&mut self) {} | ||
228 | fn fooo(&mut self) {} | ||
229 | }"#, | ||
230 | ) | ||
231 | } | ||
200 | } | 232 | } |