diff options
Diffstat (limited to 'crates/ide_assists')
-rw-r--r-- | crates/ide_assists/src/handlers/merge_imports.rs | 4 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/pull_assignment_up.rs | 50 | ||||
-rw-r--r-- | crates/ide_assists/src/tests.rs | 2 |
3 files changed, 37 insertions, 19 deletions
diff --git a/crates/ide_assists/src/handlers/merge_imports.rs b/crates/ide_assists/src/handlers/merge_imports.rs index add7b8e37..3cd090737 100644 --- a/crates/ide_assists/src/handlers/merge_imports.rs +++ b/crates/ide_assists/src/handlers/merge_imports.rs | |||
@@ -27,14 +27,14 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext) -> Option<() | |||
27 | if let Some(use_item) = tree.syntax().parent().and_then(ast::Use::cast) { | 27 | if let Some(use_item) = tree.syntax().parent().and_then(ast::Use::cast) { |
28 | let (merged, to_remove) = | 28 | let (merged, to_remove) = |
29 | next_prev().filter_map(|dir| neighbor(&use_item, dir)).find_map(|use_item2| { | 29 | next_prev().filter_map(|dir| neighbor(&use_item, dir)).find_map(|use_item2| { |
30 | try_merge_imports(&use_item, &use_item2, MergeBehavior::Full).zip(Some(use_item2)) | 30 | try_merge_imports(&use_item, &use_item2, MergeBehavior::Crate).zip(Some(use_item2)) |
31 | })?; | 31 | })?; |
32 | 32 | ||
33 | imports = Some((use_item, merged, to_remove)); | 33 | imports = Some((use_item, merged, to_remove)); |
34 | } else { | 34 | } else { |
35 | let (merged, to_remove) = | 35 | let (merged, to_remove) = |
36 | next_prev().filter_map(|dir| neighbor(&tree, dir)).find_map(|use_tree| { | 36 | next_prev().filter_map(|dir| neighbor(&tree, dir)).find_map(|use_tree| { |
37 | try_merge_trees(&tree, &use_tree, MergeBehavior::Full).zip(Some(use_tree)) | 37 | try_merge_trees(&tree, &use_tree, MergeBehavior::Crate).zip(Some(use_tree)) |
38 | })?; | 38 | })?; |
39 | 39 | ||
40 | uses = Some((tree.clone(), merged, to_remove)) | 40 | uses = Some((tree.clone(), merged, to_remove)) |
diff --git a/crates/ide_assists/src/handlers/pull_assignment_up.rs b/crates/ide_assists/src/handlers/pull_assignment_up.rs index 28d14b9c3..3128faa68 100644 --- a/crates/ide_assists/src/handlers/pull_assignment_up.rs +++ b/crates/ide_assists/src/handlers/pull_assignment_up.rs | |||
@@ -60,6 +60,12 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Opti | |||
60 | return None; | 60 | return None; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | if let Some(parent) = tgt.syntax().parent() { | ||
64 | if matches!(parent.kind(), syntax::SyntaxKind::BIN_EXPR | syntax::SyntaxKind::LET_STMT) { | ||
65 | return None; | ||
66 | } | ||
67 | } | ||
68 | |||
63 | acc.add( | 69 | acc.add( |
64 | AssistId("pull_assignment_up", AssistKind::RefactorExtract), | 70 | AssistId("pull_assignment_up", AssistKind::RefactorExtract), |
65 | "Pull assignment up", | 71 | "Pull assignment up", |
@@ -74,7 +80,13 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Opti | |||
74 | let tgt = edit.make_ast_mut(tgt); | 80 | let tgt = edit.make_ast_mut(tgt); |
75 | 81 | ||
76 | for (stmt, rhs) in assignments { | 82 | for (stmt, rhs) in assignments { |
77 | ted::replace(stmt.syntax(), rhs.syntax()); | 83 | let mut stmt = stmt.syntax().clone(); |
84 | if let Some(parent) = stmt.parent() { | ||
85 | if ast::ExprStmt::cast(parent.clone()).is_some() { | ||
86 | stmt = parent.clone(); | ||
87 | } | ||
88 | } | ||
89 | ted::replace(stmt, rhs.syntax()); | ||
78 | } | 90 | } |
79 | let assign_expr = make::expr_assignment(collector.common_lhs, tgt.clone()); | 91 | let assign_expr = make::expr_assignment(collector.common_lhs, tgt.clone()); |
80 | let assign_stmt = make::expr_stmt(assign_expr); | 92 | let assign_stmt = make::expr_stmt(assign_expr); |
@@ -87,7 +99,7 @@ pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Opti | |||
87 | struct AssignmentsCollector<'a> { | 99 | struct AssignmentsCollector<'a> { |
88 | sema: &'a hir::Semantics<'a, ide_db::RootDatabase>, | 100 | sema: &'a hir::Semantics<'a, ide_db::RootDatabase>, |
89 | common_lhs: ast::Expr, | 101 | common_lhs: ast::Expr, |
90 | assignments: Vec<(ast::ExprStmt, ast::Expr)>, | 102 | assignments: Vec<(ast::BinExpr, ast::Expr)>, |
91 | } | 103 | } |
92 | 104 | ||
93 | impl<'a> AssignmentsCollector<'a> { | 105 | impl<'a> AssignmentsCollector<'a> { |
@@ -95,6 +107,7 @@ impl<'a> AssignmentsCollector<'a> { | |||
95 | for arm in match_expr.match_arm_list()?.arms() { | 107 | for arm in match_expr.match_arm_list()?.arms() { |
96 | match arm.expr()? { | 108 | match arm.expr()? { |
97 | ast::Expr::BlockExpr(block) => self.collect_block(&block)?, | 109 | ast::Expr::BlockExpr(block) => self.collect_block(&block)?, |
110 | ast::Expr::BinExpr(expr) => self.collect_expr(&expr)?, | ||
98 | _ => return None, | 111 | _ => return None, |
99 | } | 112 | } |
100 | } | 113 | } |
@@ -114,24 +127,30 @@ impl<'a> AssignmentsCollector<'a> { | |||
114 | } | 127 | } |
115 | } | 128 | } |
116 | fn collect_block(&mut self, block: &ast::BlockExpr) -> Option<()> { | 129 | fn collect_block(&mut self, block: &ast::BlockExpr) -> Option<()> { |
117 | if block.tail_expr().is_some() { | 130 | let last_expr = block.tail_expr().or_else(|| { |
118 | return None; | 131 | if let ast::Stmt::ExprStmt(stmt) = block.statements().last()? { |
119 | } | 132 | stmt.expr() |
120 | 133 | } else { | |
121 | let last_stmt = block.statements().last()?; | 134 | None |
122 | if let ast::Stmt::ExprStmt(stmt) = last_stmt { | ||
123 | if let ast::Expr::BinExpr(expr) = stmt.expr()? { | ||
124 | if expr.op_kind()? == ast::BinOp::Assignment | ||
125 | && is_equivalent(self.sema, &expr.lhs()?, &self.common_lhs) | ||
126 | { | ||
127 | self.assignments.push((stmt, expr.rhs()?)); | ||
128 | return Some(()); | ||
129 | } | ||
130 | } | 135 | } |
136 | })?; | ||
137 | |||
138 | if let ast::Expr::BinExpr(expr) = last_expr { | ||
139 | return self.collect_expr(&expr); | ||
131 | } | 140 | } |
132 | 141 | ||
133 | None | 142 | None |
134 | } | 143 | } |
144 | |||
145 | fn collect_expr(&mut self, expr: &ast::BinExpr) -> Option<()> { | ||
146 | if expr.op_kind()? == ast::BinOp::Assignment | ||
147 | && is_equivalent(self.sema, &expr.lhs()?, &self.common_lhs) | ||
148 | { | ||
149 | self.assignments.push((expr.clone(), expr.rhs()?)); | ||
150 | return Some(()); | ||
151 | } | ||
152 | None | ||
153 | } | ||
135 | } | 154 | } |
136 | 155 | ||
137 | fn is_equivalent( | 156 | fn is_equivalent( |
@@ -241,7 +260,6 @@ fn foo() { | |||
241 | } | 260 | } |
242 | 261 | ||
243 | #[test] | 262 | #[test] |
244 | #[ignore] | ||
245 | fn test_pull_assignment_up_assignment_expressions() { | 263 | fn test_pull_assignment_up_assignment_expressions() { |
246 | check_assist( | 264 | check_assist( |
247 | pull_assignment_up, | 265 | pull_assignment_up, |
diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs index 9c2847998..0d3969c36 100644 --- a/crates/ide_assists/src/tests.rs +++ b/crates/ide_assists/src/tests.rs | |||
@@ -21,7 +21,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig { | |||
21 | snippet_cap: SnippetCap::new(true), | 21 | snippet_cap: SnippetCap::new(true), |
22 | allowed: None, | 22 | allowed: None, |
23 | insert_use: InsertUseConfig { | 23 | insert_use: InsertUseConfig { |
24 | merge: Some(MergeBehavior::Full), | 24 | merge: Some(MergeBehavior::Crate), |
25 | prefix_kind: hir::PrefixKind::Plain, | 25 | prefix_kind: hir::PrefixKind::Plain, |
26 | group: true, | 26 | group: true, |
27 | }, | 27 | }, |