aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/handlers')
-rw-r--r--crates/ra_assists/src/handlers/change_return_type_to_result.rs73
-rw-r--r--crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs16
-rw-r--r--crates/ra_assists/src/handlers/move_guard.rs222
-rw-r--r--crates/ra_assists/src/handlers/replace_if_let_with_match.rs6
-rw-r--r--crates/ra_assists/src/handlers/unwrap_block.rs3
5 files changed, 157 insertions, 163 deletions
diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
index d5a68a24c..be480943c 100644
--- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs
+++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
@@ -1,10 +1,12 @@
1use std::iter;
2
1use syntax::{ 3use syntax::{
2 ast::{self, BlockExpr, Expr, LoopBodyOwner}, 4 ast::{self, make, BlockExpr, Expr, LoopBodyOwner},
3 AstNode, SyntaxNode, 5 AstNode, SyntaxNode,
4}; 6};
7use test_utils::mark;
5 8
6use crate::{AssistContext, AssistId, AssistKind, Assists}; 9use crate::{AssistContext, AssistId, AssistKind, Assists};
7use test_utils::mark;
8 10
9// Assist: change_return_type_to_result 11// Assist: change_return_type_to_result
10// 12//
@@ -44,7 +46,13 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex
44 tail_return_expr_collector.collect_tail_exprs(block_expr); 46 tail_return_expr_collector.collect_tail_exprs(block_expr);
45 47
46 for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { 48 for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap {
47 builder.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); 49 let ok_wrapped = make::expr_call(
50 make::expr_path(make::path_unqualified(make::path_segment(make::name_ref(
51 "Ok",
52 )))),
53 make::arg_list(iter::once(ret_expr_arg.clone())),
54 );
55 builder.replace_ast(ret_expr_arg, ok_wrapped);
48 } 56 }
49 57
50 match ctx.config.snippet_cap { 58 match ctx.config.snippet_cap {
@@ -60,7 +68,7 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex
60} 68}
61 69
62struct TailReturnCollector { 70struct TailReturnCollector {
63 exprs_to_wrap: Vec<SyntaxNode>, 71 exprs_to_wrap: Vec<ast::Expr>,
64} 72}
65 73
66impl TailReturnCollector { 74impl TailReturnCollector {
@@ -86,7 +94,8 @@ impl TailReturnCollector {
86 if let Some(last_exprs) = get_tail_expr_from_block(&expr) { 94 if let Some(last_exprs) = get_tail_expr_from_block(&expr) {
87 for last_expr in last_exprs { 95 for last_expr in last_exprs {
88 let last_expr = match last_expr { 96 let last_expr = match last_expr {
89 NodeType::Node(expr) | NodeType::Leaf(expr) => expr, 97 NodeType::Node(expr) => expr,
98 NodeType::Leaf(expr) => expr.syntax().clone(),
90 }; 99 };
91 100
92 if let Some(last_expr) = Expr::cast(last_expr.clone()) { 101 if let Some(last_expr) = Expr::cast(last_expr.clone()) {
@@ -113,12 +122,12 @@ impl TailReturnCollector {
113 } 122 }
114 Expr::ReturnExpr(ret_expr) => { 123 Expr::ReturnExpr(ret_expr) => {
115 if let Some(ret_expr_arg) = &ret_expr.expr() { 124 if let Some(ret_expr_arg) = &ret_expr.expr() {
116 self.exprs_to_wrap.push(ret_expr_arg.syntax().clone()); 125 self.exprs_to_wrap.push(ret_expr_arg.clone());
117 } 126 }
118 } 127 }
119 Expr::BreakExpr(break_expr) if collect_break => { 128 Expr::BreakExpr(break_expr) if collect_break => {
120 if let Some(break_expr_arg) = &break_expr.expr() { 129 if let Some(break_expr_arg) = &break_expr.expr() {
121 self.exprs_to_wrap.push(break_expr_arg.syntax().clone()); 130 self.exprs_to_wrap.push(break_expr_arg.clone());
122 } 131 }
123 } 132 }
124 Expr::IfExpr(if_expr) => { 133 Expr::IfExpr(if_expr) => {
@@ -166,14 +175,11 @@ impl TailReturnCollector {
166 NodeType::Leaf(expr) => { 175 NodeType::Leaf(expr) => {
167 self.exprs_to_wrap.push(expr.clone()); 176 self.exprs_to_wrap.push(expr.clone());
168 } 177 }
169 NodeType::Node(expr) => match &Expr::cast(expr.clone()) { 178 NodeType::Node(expr) => {
170 Some(last_expr) => { 179 if let Some(last_expr) = Expr::cast(expr.clone()) {
171 self.fetch_tail_exprs(last_expr); 180 self.fetch_tail_exprs(&last_expr);
172 }
173 None => {
174 self.exprs_to_wrap.push(expr.clone());
175 } 181 }
176 }, 182 }
177 } 183 }
178 } 184 }
179 } 185 }
@@ -182,7 +188,7 @@ impl TailReturnCollector {
182 188
183#[derive(Debug)] 189#[derive(Debug)]
184enum NodeType { 190enum NodeType {
185 Leaf(SyntaxNode), 191 Leaf(ast::Expr),
186 Node(SyntaxNode), 192 Node(SyntaxNode),
187} 193}
188 194
@@ -233,25 +239,26 @@ fn get_tail_expr_from_block(expr: &Expr) -> Option<Vec<NodeType>> {
233 239
234 Some(arms) 240 Some(arms)
235 } 241 }
236 Expr::BreakExpr(expr) => expr.expr().map(|e| vec![NodeType::Leaf(e.syntax().clone())]), 242 Expr::BreakExpr(expr) => expr.expr().map(|e| vec![NodeType::Leaf(e)]),
237 Expr::ReturnExpr(ret_expr) => Some(vec![NodeType::Node(ret_expr.syntax().clone())]), 243 Expr::ReturnExpr(ret_expr) => Some(vec![NodeType::Node(ret_expr.syntax().clone())]),
238 Expr::CallExpr(call_expr) => Some(vec![NodeType::Leaf(call_expr.syntax().clone())]), 244
239 Expr::Literal(lit_expr) => Some(vec![NodeType::Leaf(lit_expr.syntax().clone())]), 245 Expr::CallExpr(_)
240 Expr::TupleExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 246 | Expr::Literal(_)
241 Expr::ArrayExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 247 | Expr::TupleExpr(_)
242 Expr::ParenExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 248 | Expr::ArrayExpr(_)
243 Expr::PathExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 249 | Expr::ParenExpr(_)
244 Expr::RecordExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 250 | Expr::PathExpr(_)
245 Expr::IndexExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 251 | Expr::RecordExpr(_)
246 Expr::MethodCallExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 252 | Expr::IndexExpr(_)
247 Expr::AwaitExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 253 | Expr::MethodCallExpr(_)
248 Expr::CastExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 254 | Expr::AwaitExpr(_)
249 Expr::RefExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 255 | Expr::CastExpr(_)
250 Expr::PrefixExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 256 | Expr::RefExpr(_)
251 Expr::RangeExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 257 | Expr::PrefixExpr(_)
252 Expr::BinExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 258 | Expr::RangeExpr(_)
253 Expr::MacroCall(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 259 | Expr::BinExpr(_)
254 Expr::BoxExpr(expr) => Some(vec![NodeType::Leaf(expr.syntax().clone())]), 260 | Expr::MacroCall(_)
261 | Expr::BoxExpr(_) => Some(vec![NodeType::Leaf(expr.clone())]),
255 _ => None, 262 _ => None,
256 } 263 }
257} 264}
diff --git a/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs
index 6e9f2d0fc..497f887cd 100644
--- a/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -1,12 +1,11 @@
1use hir::{EnumVariant, Module, ModuleDef, Name}; 1use hir::{EnumVariant, Module, ModuleDef, Name};
2use ra_db::FileId; 2use ra_db::FileId;
3use ra_fmt::leading_indent;
4use ra_ide_db::{defs::Definition, search::Reference, RootDatabase}; 3use ra_ide_db::{defs::Definition, search::Reference, RootDatabase};
5use rustc_hash::FxHashSet; 4use rustc_hash::FxHashSet;
6use syntax::{ 5use syntax::{
7 algo::find_node_at_offset, 6 algo::find_node_at_offset,
8 ast::{self, ArgListOwner, AstNode, NameOwner, VisibilityOwner}, 7 ast::{self, edit::IndentLevel, ArgListOwner, AstNode, NameOwner, VisibilityOwner},
9 SourceFile, SyntaxNode, TextRange, TextSize, 8 SourceFile, TextRange, TextSize,
10}; 9};
11 10
12use crate::{ 11use crate::{
@@ -72,7 +71,7 @@ pub(crate) fn extract_struct_from_enum_variant(
72 } 71 }
73 extract_struct_def( 72 extract_struct_def(
74 builder, 73 builder,
75 enum_ast.syntax(), 74 &enum_ast,
76 &variant_name, 75 &variant_name,
77 &field_list.to_string(), 76 &field_list.to_string(),
78 start_offset, 77 start_offset,
@@ -112,9 +111,10 @@ fn insert_import(
112 Some(()) 111 Some(())
113} 112}
114 113
114// FIXME: this should use strongly-typed `make`, rather than string manipulation.
115fn extract_struct_def( 115fn extract_struct_def(
116 builder: &mut AssistBuilder, 116 builder: &mut AssistBuilder,
117 enum_ast: &SyntaxNode, 117 enum_: &ast::Enum,
118 variant_name: &str, 118 variant_name: &str,
119 variant_list: &str, 119 variant_list: &str,
120 start_offset: TextSize, 120 start_offset: TextSize,
@@ -126,11 +126,7 @@ fn extract_struct_def(
126 } else { 126 } else {
127 "".to_string() 127 "".to_string()
128 }; 128 };
129 let indent = if let Some(indent) = leading_indent(enum_ast) { 129 let indent = IndentLevel::from_node(enum_.syntax());
130 indent.to_string()
131 } else {
132 "".to_string()
133 };
134 let struct_def = format!( 130 let struct_def = format!(
135 r#"{}struct {}{}; 131 r#"{}struct {}{};
136 132
diff --git a/crates/ra_assists/src/handlers/move_guard.rs b/crates/ra_assists/src/handlers/move_guard.rs
index c62ebc306..452115fe6 100644
--- a/crates/ra_assists/src/handlers/move_guard.rs
+++ b/crates/ra_assists/src/handlers/move_guard.rs
@@ -1,5 +1,5 @@
1use syntax::{ 1use syntax::{
2 ast::{AstNode, IfExpr, MatchArm}, 2 ast::{edit::AstNodeEdit, make, AstNode, IfExpr, MatchArm},
3 SyntaxKind::WHITESPACE, 3 SyntaxKind::WHITESPACE,
4}; 4};
5 5
@@ -25,7 +25,9 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
25// 25//
26// fn handle(action: Action) { 26// fn handle(action: Action) {
27// match action { 27// match action {
28// Action::Move { distance } => if distance > 10 { foo() }, 28// Action::Move { distance } => if distance > 10 {
29// foo()
30// },
29// _ => (), 31// _ => (),
30// } 32// }
31// } 33// }
@@ -35,9 +37,13 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext) ->
35 let guard = match_arm.guard()?; 37 let guard = match_arm.guard()?;
36 let space_before_guard = guard.syntax().prev_sibling_or_token(); 38 let space_before_guard = guard.syntax().prev_sibling_or_token();
37 39
38 let guard_conditions = guard.expr()?; 40 let guard_condition = guard.expr()?;
39 let arm_expr = match_arm.expr()?; 41 let arm_expr = match_arm.expr()?;
40 let buf = format!("if {} {{ {} }}", guard_conditions.syntax().text(), arm_expr.syntax().text()); 42 let if_expr = make::expr_if(
43 make::condition(guard_condition, None),
44 make::block_expr(None, Some(arm_expr.clone())),
45 )
46 .indent(arm_expr.indent_level());
41 47
42 let target = guard.syntax().text_range(); 48 let target = guard.syntax().text_range();
43 acc.add( 49 acc.add(
@@ -53,7 +59,7 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext) ->
53 }; 59 };
54 60
55 edit.delete(guard.syntax().text_range()); 61 edit.delete(guard.syntax().text_range());
56 edit.replace_node_and_indent(arm_expr.syntax(), buf); 62 edit.replace_ast(arm_expr, if_expr);
57 }, 63 },
58 ) 64 )
59} 65}
@@ -134,16 +140,14 @@ mod tests {
134 check_assist_target( 140 check_assist_target(
135 move_guard_to_arm_body, 141 move_guard_to_arm_body,
136 r#" 142 r#"
137 fn f() { 143fn main() {
138 let t = 'a'; 144 match 92 {
139 let chars = "abcd"; 145 x <|>if x > 10 => false,
140 match t { 146 _ => true
141 '\r' <|>if chars.clone().next() == Some('\n') => false, 147 }
142 _ => true 148}
143 } 149"#,
144 } 150 r#"if x > 10"#,
145 "#,
146 r#"if chars.clone().next() == Some('\n')"#,
147 ); 151 );
148 } 152 }
149 153
@@ -152,25 +156,23 @@ mod tests {
152 check_assist( 156 check_assist(
153 move_guard_to_arm_body, 157 move_guard_to_arm_body,
154 r#" 158 r#"
155 fn f() { 159fn main() {
156 let t = 'a'; 160 match 92 {
157 let chars = "abcd"; 161 x <|>if x > 10 => false,
158 match t { 162 _ => true
159 '\r' <|>if chars.clone().next() == Some('\n') => false, 163 }
160 _ => true 164}
161 } 165"#,
162 }
163 "#,
164 r#" 166 r#"
165 fn f() { 167fn main() {
166 let t = 'a'; 168 match 92 {
167 let chars = "abcd"; 169 x => if x > 10 {
168 match t { 170 false
169 '\r' => if chars.clone().next() == Some('\n') { false }, 171 },
170 _ => true 172 _ => true
171 } 173 }
172 } 174}
173 "#, 175"#,
174 ); 176 );
175 } 177 }
176 178
@@ -179,21 +181,23 @@ mod tests {
179 check_assist( 181 check_assist(
180 move_guard_to_arm_body, 182 move_guard_to_arm_body,
181 r#" 183 r#"
182 fn f() { 184fn main() {
183 match x { 185 match 92 {
184 <|>y @ 4 | y @ 5 if y > 5 => true, 186 <|>x @ 4 | x @ 5 if x > 5 => true,
185 _ => false 187 _ => false
186 } 188 }
187 } 189}
188 "#, 190"#,
189 r#" 191 r#"
190 fn f() { 192fn main() {
191 match x { 193 match 92 {
192 y @ 4 | y @ 5 => if y > 5 { true }, 194 x @ 4 | x @ 5 => if x > 5 {
193 _ => false 195 true
194 } 196 },
195 } 197 _ => false
196 "#, 198 }
199}
200"#,
197 ); 201 );
198 } 202 }
199 203
@@ -202,25 +206,21 @@ mod tests {
202 check_assist( 206 check_assist(
203 move_arm_cond_to_match_guard, 207 move_arm_cond_to_match_guard,
204 r#" 208 r#"
205 fn f() { 209fn main() {
206 let t = 'a'; 210 match 92 {
207 let chars = "abcd"; 211 x => if x > 10 { <|>false },
208 match t { 212 _ => true
209 '\r' => if chars.clone().next() == Some('\n') { <|>false }, 213 }
210 _ => true 214}
211 } 215"#,
212 }
213 "#,
214 r#" 216 r#"
215 fn f() { 217fn main() {
216 let t = 'a'; 218 match 92 {
217 let chars = "abcd"; 219 x if x > 10 => false,
218 match t { 220 _ => true
219 '\r' if chars.clone().next() == Some('\n') => false, 221 }
220 _ => true 222}
221 } 223"#,
222 }
223 "#,
224 ); 224 );
225 } 225 }
226 226
@@ -229,15 +229,13 @@ mod tests {
229 check_assist_not_applicable( 229 check_assist_not_applicable(
230 move_arm_cond_to_match_guard, 230 move_arm_cond_to_match_guard,
231 r#" 231 r#"
232 fn f() { 232fn main() {
233 let t = 'a'; 233 match 92 {
234 let chars = "abcd"; 234 x => if let 62 = x { <|>false },
235 match t { 235 _ => true
236 '\r' => if let Some(_) = chars.clone().next() { <|>false }, 236 }
237 _ => true 237}
238 } 238"#,
239 }
240 "#,
241 ); 239 );
242 } 240 }
243 241
@@ -246,25 +244,21 @@ mod tests {
246 check_assist( 244 check_assist(
247 move_arm_cond_to_match_guard, 245 move_arm_cond_to_match_guard,
248 r#" 246 r#"
249 fn f() { 247fn main() {
250 let t = 'a'; 248 match 92 {
251 let chars = "abcd"; 249 x => if x > 10 { <|> },
252 match t { 250 _ => true
253 '\r' => if chars.clone().next().is_some() { <|> }, 251 }
254 _ => true 252}
255 } 253"#,
256 }
257 "#,
258 r#" 254 r#"
259 fn f() { 255fn main() {
260 let t = 'a'; 256 match 92 {
261 let chars = "abcd"; 257 x if x > 10 => { },
262 match t { 258 _ => true
263 '\r' if chars.clone().next().is_some() => { }, 259 }
264 _ => true 260}
265 } 261"#,
266 }
267 "#,
268 ); 262 );
269 } 263 }
270 264
@@ -273,31 +267,27 @@ mod tests {
273 check_assist( 267 check_assist(
274 move_arm_cond_to_match_guard, 268 move_arm_cond_to_match_guard,
275 r#" 269 r#"
276 fn f() { 270fn main() {
277 let mut t = 'a'; 271 match 92 {
278 let chars = "abcd"; 272 x => if x > 10 {
279 match t { 273 92;<|>
280 '\r' => if chars.clone().next().is_some() { 274 false
281 t = 'e';<|> 275 },
282 false 276 _ => true
283 }, 277 }
284 _ => true 278}
285 } 279"#,
286 }
287 "#,
288 r#" 280 r#"
289 fn f() { 281fn main() {
290 let mut t = 'a'; 282 match 92 {
291 let chars = "abcd"; 283 x if x > 10 => {
292 match t { 284 92;
293 '\r' if chars.clone().next().is_some() => { 285 false
294 t = 'e'; 286 },
295 false 287 _ => true
296 }, 288 }
297 _ => true 289}
298 } 290"#,
299 }
300 "#,
301 ); 291 );
302 } 292 }
303} 293}
diff --git a/crates/ra_assists/src/handlers/replace_if_let_with_match.rs b/crates/ra_assists/src/handlers/replace_if_let_with_match.rs
index 2442f049b..79097621e 100644
--- a/crates/ra_assists/src/handlers/replace_if_let_with_match.rs
+++ b/crates/ra_assists/src/handlers/replace_if_let_with_match.rs
@@ -1,4 +1,3 @@
1use ra_fmt::unwrap_trivial_block;
2use syntax::{ 1use syntax::{
3 ast::{ 2 ast::{
4 self, 3 self,
@@ -8,7 +7,10 @@ use syntax::{
8 AstNode, 7 AstNode,
9}; 8};
10 9
11use crate::{utils::TryEnum, AssistContext, AssistId, AssistKind, Assists}; 10use crate::{
11 utils::{unwrap_trivial_block, TryEnum},
12 AssistContext, AssistId, AssistKind, Assists,
13};
12 14
13// Assist: replace_if_let_with_match 15// Assist: replace_if_let_with_match
14// 16//
diff --git a/crates/ra_assists/src/handlers/unwrap_block.rs b/crates/ra_assists/src/handlers/unwrap_block.rs
index 2879090b8..3851aeb3e 100644
--- a/crates/ra_assists/src/handlers/unwrap_block.rs
+++ b/crates/ra_assists/src/handlers/unwrap_block.rs
@@ -1,4 +1,3 @@
1use ra_fmt::unwrap_trivial_block;
2use syntax::{ 1use syntax::{
3 ast::{ 2 ast::{
4 self, 3 self,
@@ -7,7 +6,7 @@ use syntax::{
7 AstNode, TextRange, T, 6 AstNode, TextRange, T,
8}; 7};
9 8
10use crate::{AssistContext, AssistId, AssistKind, Assists}; 9use crate::{utils::unwrap_trivial_block, AssistContext, AssistId, AssistKind, Assists};
11 10
12// Assist: unwrap_block 11// Assist: unwrap_block
13// 12//