diff options
Diffstat (limited to 'crates/ide_assists/src/handlers/extract_function.rs')
-rw-r--r-- | crates/ide_assists/src/handlers/extract_function.rs | 197 |
1 files changed, 94 insertions, 103 deletions
diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs index b30652a9d..6311afc1f 100644 --- a/crates/ide_assists/src/handlers/extract_function.rs +++ b/crates/ide_assists/src/handlers/extract_function.rs | |||
@@ -10,18 +10,18 @@ use ide_db::{ | |||
10 | use itertools::Itertools; | 10 | use itertools::Itertools; |
11 | use stdx::format_to; | 11 | use stdx::format_to; |
12 | use syntax::{ | 12 | use syntax::{ |
13 | algo::SyntaxRewriter, | ||
14 | ast::{ | 13 | ast::{ |
15 | self, | 14 | self, |
16 | edit::{AstNodeEdit, IndentLevel}, | 15 | edit::{AstNodeEdit, IndentLevel}, |
17 | AstNode, | 16 | AstNode, |
18 | }, | 17 | }, |
18 | ted, | ||
19 | SyntaxKind::{self, BLOCK_EXPR, BREAK_EXPR, COMMENT, PATH_EXPR, RETURN_EXPR}, | 19 | SyntaxKind::{self, BLOCK_EXPR, BREAK_EXPR, COMMENT, PATH_EXPR, RETURN_EXPR}, |
20 | SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset, WalkEvent, T, | 20 | SyntaxNode, SyntaxToken, TextRange, TextSize, TokenAtOffset, WalkEvent, T, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | use crate::{ | 23 | use crate::{ |
24 | assist_context::{AssistContext, Assists}, | 24 | assist_context::{AssistContext, Assists, TreeMutator}, |
25 | AssistId, | 25 | AssistId, |
26 | }; | 26 | }; |
27 | 27 | ||
@@ -956,10 +956,10 @@ fn format_replacement(ctx: &AssistContext, fun: &Function, indent: IndentLevel) | |||
956 | let args = fun.params.iter().map(|param| param.to_arg(ctx)); | 956 | let args = fun.params.iter().map(|param| param.to_arg(ctx)); |
957 | let args = make::arg_list(args); | 957 | let args = make::arg_list(args); |
958 | let call_expr = if fun.self_param.is_some() { | 958 | let call_expr = if fun.self_param.is_some() { |
959 | let self_arg = make::expr_path(make_path_from_text("self")); | 959 | let self_arg = make::expr_path(make::ext::ident_path("self")); |
960 | make::expr_method_call(self_arg, &fun.name, args) | 960 | make::expr_method_call(self_arg, &fun.name, args) |
961 | } else { | 961 | } else { |
962 | let func = make::expr_path(make_path_from_text(&fun.name)); | 962 | let func = make::expr_path(make::ext::ident_path(&fun.name)); |
963 | make::expr_call(func, args) | 963 | make::expr_call(func, args) |
964 | }; | 964 | }; |
965 | 965 | ||
@@ -1054,11 +1054,11 @@ impl FlowHandler { | |||
1054 | make::expr_if(condition, block, None) | 1054 | make::expr_if(condition, block, None) |
1055 | } | 1055 | } |
1056 | FlowHandler::IfOption { action } => { | 1056 | FlowHandler::IfOption { action } => { |
1057 | let path = make_path_from_text("Some"); | 1057 | let path = make::ext::ident_path("Some"); |
1058 | let value_pat = make::ident_pat(make::name("value")); | 1058 | let value_pat = make::ident_pat(make::name("value")); |
1059 | let pattern = make::tuple_struct_pat(path, iter::once(value_pat.into())); | 1059 | let pattern = make::tuple_struct_pat(path, iter::once(value_pat.into())); |
1060 | let cond = make::condition(call_expr, Some(pattern.into())); | 1060 | let cond = make::condition(call_expr, Some(pattern.into())); |
1061 | let value = make::expr_path(make_path_from_text("value")); | 1061 | let value = make::expr_path(make::ext::ident_path("value")); |
1062 | let action_expr = action.make_result_handler(Some(value)); | 1062 | let action_expr = action.make_result_handler(Some(value)); |
1063 | let action_stmt = make::expr_stmt(action_expr); | 1063 | let action_stmt = make::expr_stmt(action_expr); |
1064 | let then = make::block_expr(iter::once(action_stmt.into()), None); | 1064 | let then = make::block_expr(iter::once(action_stmt.into()), None); |
@@ -1068,14 +1068,14 @@ impl FlowHandler { | |||
1068 | let some_name = "value"; | 1068 | let some_name = "value"; |
1069 | 1069 | ||
1070 | let some_arm = { | 1070 | let some_arm = { |
1071 | let path = make_path_from_text("Some"); | 1071 | let path = make::ext::ident_path("Some"); |
1072 | let value_pat = make::ident_pat(make::name(some_name)); | 1072 | let value_pat = make::ident_pat(make::name(some_name)); |
1073 | let pat = make::tuple_struct_pat(path, iter::once(value_pat.into())); | 1073 | let pat = make::tuple_struct_pat(path, iter::once(value_pat.into())); |
1074 | let value = make::expr_path(make_path_from_text(some_name)); | 1074 | let value = make::expr_path(make::ext::ident_path(some_name)); |
1075 | make::match_arm(iter::once(pat.into()), value) | 1075 | make::match_arm(iter::once(pat.into()), value) |
1076 | }; | 1076 | }; |
1077 | let none_arm = { | 1077 | let none_arm = { |
1078 | let path = make_path_from_text("None"); | 1078 | let path = make::ext::ident_path("None"); |
1079 | let pat = make::path_pat(path); | 1079 | let pat = make::path_pat(path); |
1080 | make::match_arm(iter::once(pat), none.make_result_handler(None)) | 1080 | make::match_arm(iter::once(pat), none.make_result_handler(None)) |
1081 | }; | 1081 | }; |
@@ -1087,17 +1087,17 @@ impl FlowHandler { | |||
1087 | let err_name = "value"; | 1087 | let err_name = "value"; |
1088 | 1088 | ||
1089 | let ok_arm = { | 1089 | let ok_arm = { |
1090 | let path = make_path_from_text("Ok"); | 1090 | let path = make::ext::ident_path("Ok"); |
1091 | let value_pat = make::ident_pat(make::name(ok_name)); | 1091 | let value_pat = make::ident_pat(make::name(ok_name)); |
1092 | let pat = make::tuple_struct_pat(path, iter::once(value_pat.into())); | 1092 | let pat = make::tuple_struct_pat(path, iter::once(value_pat.into())); |
1093 | let value = make::expr_path(make_path_from_text(ok_name)); | 1093 | let value = make::expr_path(make::ext::ident_path(ok_name)); |
1094 | make::match_arm(iter::once(pat.into()), value) | 1094 | make::match_arm(iter::once(pat.into()), value) |
1095 | }; | 1095 | }; |
1096 | let err_arm = { | 1096 | let err_arm = { |
1097 | let path = make_path_from_text("Err"); | 1097 | let path = make::ext::ident_path("Err"); |
1098 | let value_pat = make::ident_pat(make::name(err_name)); | 1098 | let value_pat = make::ident_pat(make::name(err_name)); |
1099 | let pat = make::tuple_struct_pat(path, iter::once(value_pat.into())); | 1099 | let pat = make::tuple_struct_pat(path, iter::once(value_pat.into())); |
1100 | let value = make::expr_path(make_path_from_text(err_name)); | 1100 | let value = make::expr_path(make::ext::ident_path(err_name)); |
1101 | make::match_arm(iter::once(pat.into()), err.make_result_handler(Some(value))) | 1101 | make::match_arm(iter::once(pat.into()), err.make_result_handler(Some(value))) |
1102 | }; | 1102 | }; |
1103 | let arms = make::match_arm_list(vec![ok_arm, err_arm]); | 1103 | let arms = make::match_arm_list(vec![ok_arm, err_arm]); |
@@ -1107,13 +1107,9 @@ impl FlowHandler { | |||
1107 | } | 1107 | } |
1108 | } | 1108 | } |
1109 | 1109 | ||
1110 | fn make_path_from_text(text: &str) -> ast::Path { | ||
1111 | make::path_unqualified(make::path_segment(make::name_ref(text))) | ||
1112 | } | ||
1113 | |||
1114 | fn path_expr_from_local(ctx: &AssistContext, var: Local) -> ast::Expr { | 1110 | fn path_expr_from_local(ctx: &AssistContext, var: Local) -> ast::Expr { |
1115 | let name = var.name(ctx.db()).unwrap().to_string(); | 1111 | let name = var.name(ctx.db()).unwrap().to_string(); |
1116 | make::expr_path(make_path_from_text(&name)) | 1112 | make::expr_path(make::ext::ident_path(&name)) |
1117 | } | 1113 | } |
1118 | 1114 | ||
1119 | fn format_function( | 1115 | fn format_function( |
@@ -1179,7 +1175,7 @@ fn make_ret_ty(ctx: &AssistContext, module: hir::Module, fun: &Function) -> Opti | |||
1179 | fun_ty.make_ty(ctx, module) | 1175 | fun_ty.make_ty(ctx, module) |
1180 | } | 1176 | } |
1181 | FlowHandler::Try { kind: TryKind::Option } => { | 1177 | FlowHandler::Try { kind: TryKind::Option } => { |
1182 | make::ty_generic(make::name_ref("Option"), iter::once(fun_ty.make_ty(ctx, module))) | 1178 | make::ext::ty_option(fun_ty.make_ty(ctx, module)) |
1183 | } | 1179 | } |
1184 | FlowHandler::Try { kind: TryKind::Result { ty: parent_ret_ty } } => { | 1180 | FlowHandler::Try { kind: TryKind::Result { ty: parent_ret_ty } } => { |
1185 | let handler_ty = parent_ret_ty | 1181 | let handler_ty = parent_ret_ty |
@@ -1187,29 +1183,21 @@ fn make_ret_ty(ctx: &AssistContext, module: hir::Module, fun: &Function) -> Opti | |||
1187 | .nth(1) | 1183 | .nth(1) |
1188 | .map(|ty| make_ty(&ty, ctx, module)) | 1184 | .map(|ty| make_ty(&ty, ctx, module)) |
1189 | .unwrap_or_else(make::ty_unit); | 1185 | .unwrap_or_else(make::ty_unit); |
1190 | make::ty_generic( | 1186 | make::ext::ty_result(fun_ty.make_ty(ctx, module), handler_ty) |
1191 | make::name_ref("Result"), | ||
1192 | vec![fun_ty.make_ty(ctx, module), handler_ty], | ||
1193 | ) | ||
1194 | } | 1187 | } |
1195 | FlowHandler::If { .. } => make::ty("bool"), | 1188 | FlowHandler::If { .. } => make::ext::ty_bool(), |
1196 | FlowHandler::IfOption { action } => { | 1189 | FlowHandler::IfOption { action } => { |
1197 | let handler_ty = action | 1190 | let handler_ty = action |
1198 | .expr_ty(ctx) | 1191 | .expr_ty(ctx) |
1199 | .map(|ty| make_ty(&ty, ctx, module)) | 1192 | .map(|ty| make_ty(&ty, ctx, module)) |
1200 | .unwrap_or_else(make::ty_unit); | 1193 | .unwrap_or_else(make::ty_unit); |
1201 | make::ty_generic(make::name_ref("Option"), iter::once(handler_ty)) | 1194 | make::ext::ty_option(handler_ty) |
1202 | } | ||
1203 | FlowHandler::MatchOption { .. } => { | ||
1204 | make::ty_generic(make::name_ref("Option"), iter::once(fun_ty.make_ty(ctx, module))) | ||
1205 | } | 1195 | } |
1196 | FlowHandler::MatchOption { .. } => make::ext::ty_option(fun_ty.make_ty(ctx, module)), | ||
1206 | FlowHandler::MatchResult { err } => { | 1197 | FlowHandler::MatchResult { err } => { |
1207 | let handler_ty = | 1198 | let handler_ty = |
1208 | err.expr_ty(ctx).map(|ty| make_ty(&ty, ctx, module)).unwrap_or_else(make::ty_unit); | 1199 | err.expr_ty(ctx).map(|ty| make_ty(&ty, ctx, module)).unwrap_or_else(make::ty_unit); |
1209 | make::ty_generic( | 1200 | make::ext::ty_result(fun_ty.make_ty(ctx, module), handler_ty) |
1210 | make::name_ref("Result"), | ||
1211 | vec![fun_ty.make_ty(ctx, module), handler_ty], | ||
1212 | ) | ||
1213 | } | 1201 | } |
1214 | }; | 1202 | }; |
1215 | Some(make::ret_type(ret_ty)) | 1203 | Some(make::ret_type(ret_ty)) |
@@ -1296,7 +1284,7 @@ fn make_body( | |||
1296 | TryKind::Option => "Some", | 1284 | TryKind::Option => "Some", |
1297 | TryKind::Result { .. } => "Ok", | 1285 | TryKind::Result { .. } => "Ok", |
1298 | }; | 1286 | }; |
1299 | let func = make::expr_path(make_path_from_text(constructor)); | 1287 | let func = make::expr_path(make::ext::ident_path(constructor)); |
1300 | let args = make::arg_list(iter::once(tail_expr)); | 1288 | let args = make::arg_list(iter::once(tail_expr)); |
1301 | make::expr_call(func, args) | 1289 | make::expr_call(func, args) |
1302 | }) | 1290 | }) |
@@ -1306,16 +1294,16 @@ fn make_body( | |||
1306 | with_tail_expr(block, lit_false.into()) | 1294 | with_tail_expr(block, lit_false.into()) |
1307 | } | 1295 | } |
1308 | FlowHandler::IfOption { .. } => { | 1296 | FlowHandler::IfOption { .. } => { |
1309 | let none = make::expr_path(make_path_from_text("None")); | 1297 | let none = make::expr_path(make::ext::ident_path("None")); |
1310 | with_tail_expr(block, none) | 1298 | with_tail_expr(block, none) |
1311 | } | 1299 | } |
1312 | FlowHandler::MatchOption { .. } => map_tail_expr(block, |tail_expr| { | 1300 | FlowHandler::MatchOption { .. } => map_tail_expr(block, |tail_expr| { |
1313 | let some = make::expr_path(make_path_from_text("Some")); | 1301 | let some = make::expr_path(make::ext::ident_path("Some")); |
1314 | let args = make::arg_list(iter::once(tail_expr)); | 1302 | let args = make::arg_list(iter::once(tail_expr)); |
1315 | make::expr_call(some, args) | 1303 | make::expr_call(some, args) |
1316 | }), | 1304 | }), |
1317 | FlowHandler::MatchResult { .. } => map_tail_expr(block, |tail_expr| { | 1305 | FlowHandler::MatchResult { .. } => map_tail_expr(block, |tail_expr| { |
1318 | let ok = make::expr_path(make_path_from_text("Ok")); | 1306 | let ok = make::expr_path(make::ext::ident_path("Ok")); |
1319 | let args = make::arg_list(iter::once(tail_expr)); | 1307 | let args = make::arg_list(iter::once(tail_expr)); |
1320 | make::expr_call(ok, args) | 1308 | make::expr_call(ok, args) |
1321 | }), | 1309 | }), |
@@ -1361,12 +1349,16 @@ fn rewrite_body_segment( | |||
1361 | syntax: &SyntaxNode, | 1349 | syntax: &SyntaxNode, |
1362 | ) -> SyntaxNode { | 1350 | ) -> SyntaxNode { |
1363 | let syntax = fix_param_usages(ctx, params, syntax); | 1351 | let syntax = fix_param_usages(ctx, params, syntax); |
1364 | update_external_control_flow(handler, &syntax) | 1352 | update_external_control_flow(handler, &syntax); |
1353 | syntax | ||
1365 | } | 1354 | } |
1366 | 1355 | ||
1367 | /// change all usages to account for added `&`/`&mut` for some params | 1356 | /// change all usages to account for added `&`/`&mut` for some params |
1368 | fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode) -> SyntaxNode { | 1357 | fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode) -> SyntaxNode { |
1369 | let mut rewriter = SyntaxRewriter::default(); | 1358 | let mut usages_for_param: Vec<(&Param, Vec<ast::Expr>)> = Vec::new(); |
1359 | |||
1360 | let tm = TreeMutator::new(syntax); | ||
1361 | |||
1370 | for param in params { | 1362 | for param in params { |
1371 | if !param.kind().is_ref() { | 1363 | if !param.kind().is_ref() { |
1372 | continue; | 1364 | continue; |
@@ -1376,101 +1368,100 @@ fn fix_param_usages(ctx: &AssistContext, params: &[Param], syntax: &SyntaxNode) | |||
1376 | let usages = usages | 1368 | let usages = usages |
1377 | .iter() | 1369 | .iter() |
1378 | .filter(|reference| syntax.text_range().contains_range(reference.range)) | 1370 | .filter(|reference| syntax.text_range().contains_range(reference.range)) |
1379 | .filter_map(|reference| path_element_of_reference(syntax, reference)); | 1371 | .filter_map(|reference| path_element_of_reference(syntax, reference)) |
1380 | for path in usages { | 1372 | .map(|expr| tm.make_mut(&expr)); |
1381 | match path.syntax().ancestors().skip(1).find_map(ast::Expr::cast) { | 1373 | |
1374 | usages_for_param.push((param, usages.collect())); | ||
1375 | } | ||
1376 | |||
1377 | let res = tm.make_syntax_mut(syntax); | ||
1378 | |||
1379 | for (param, usages) in usages_for_param { | ||
1380 | for usage in usages { | ||
1381 | match usage.syntax().ancestors().skip(1).find_map(ast::Expr::cast) { | ||
1382 | Some(ast::Expr::MethodCallExpr(_)) | Some(ast::Expr::FieldExpr(_)) => { | 1382 | Some(ast::Expr::MethodCallExpr(_)) | Some(ast::Expr::FieldExpr(_)) => { |
1383 | // do nothing | 1383 | // do nothing |
1384 | } | 1384 | } |
1385 | Some(ast::Expr::RefExpr(node)) | 1385 | Some(ast::Expr::RefExpr(node)) |
1386 | if param.kind() == ParamKind::MutRef && node.mut_token().is_some() => | 1386 | if param.kind() == ParamKind::MutRef && node.mut_token().is_some() => |
1387 | { | 1387 | { |
1388 | rewriter.replace_ast(&node.clone().into(), &node.expr().unwrap()); | 1388 | ted::replace(node.syntax(), node.expr().unwrap().syntax()); |
1389 | } | 1389 | } |
1390 | Some(ast::Expr::RefExpr(node)) | 1390 | Some(ast::Expr::RefExpr(node)) |
1391 | if param.kind() == ParamKind::SharedRef && node.mut_token().is_none() => | 1391 | if param.kind() == ParamKind::SharedRef && node.mut_token().is_none() => |
1392 | { | 1392 | { |
1393 | rewriter.replace_ast(&node.clone().into(), &node.expr().unwrap()); | 1393 | ted::replace(node.syntax(), node.expr().unwrap().syntax()); |
1394 | } | 1394 | } |
1395 | Some(_) | None => { | 1395 | Some(_) | None => { |
1396 | rewriter.replace_ast(&path, &make::expr_prefix(T![*], path.clone())); | 1396 | let p = &make::expr_prefix(T![*], usage.clone()).clone_for_update(); |
1397 | ted::replace(usage.syntax(), p.syntax()) | ||
1397 | } | 1398 | } |
1398 | }; | 1399 | } |
1399 | } | 1400 | } |
1400 | } | 1401 | } |
1401 | 1402 | ||
1402 | rewriter.rewrite(syntax) | 1403 | res |
1403 | } | 1404 | } |
1404 | 1405 | ||
1405 | fn update_external_control_flow(handler: &FlowHandler, syntax: &SyntaxNode) -> SyntaxNode { | 1406 | fn update_external_control_flow(handler: &FlowHandler, syntax: &SyntaxNode) { |
1406 | let mut rewriter = SyntaxRewriter::default(); | ||
1407 | |||
1408 | let mut nested_loop = None; | 1407 | let mut nested_loop = None; |
1409 | let mut nested_scope = None; | 1408 | let mut nested_scope = None; |
1410 | for event in syntax.preorder() { | 1409 | for event in syntax.preorder() { |
1411 | let node = match event { | 1410 | match event { |
1412 | WalkEvent::Enter(e) => { | 1411 | WalkEvent::Enter(e) => match e.kind() { |
1413 | match e.kind() { | 1412 | SyntaxKind::LOOP_EXPR | SyntaxKind::WHILE_EXPR | SyntaxKind::FOR_EXPR => { |
1414 | SyntaxKind::LOOP_EXPR | SyntaxKind::WHILE_EXPR | SyntaxKind::FOR_EXPR => { | 1413 | if nested_loop.is_none() { |
1415 | if nested_loop.is_none() { | 1414 | nested_loop = Some(e.clone()); |
1416 | nested_loop = Some(e.clone()); | ||
1417 | } | ||
1418 | } | 1415 | } |
1419 | SyntaxKind::FN | 1416 | } |
1420 | | SyntaxKind::CONST | 1417 | SyntaxKind::FN |
1421 | | SyntaxKind::STATIC | 1418 | | SyntaxKind::CONST |
1422 | | SyntaxKind::IMPL | 1419 | | SyntaxKind::STATIC |
1423 | | SyntaxKind::MODULE => { | 1420 | | SyntaxKind::IMPL |
1424 | if nested_scope.is_none() { | 1421 | | SyntaxKind::MODULE => { |
1425 | nested_scope = Some(e.clone()); | 1422 | if nested_scope.is_none() { |
1426 | } | 1423 | nested_scope = Some(e.clone()); |
1427 | } | 1424 | } |
1428 | _ => {} | ||
1429 | } | 1425 | } |
1430 | e | 1426 | _ => {} |
1431 | } | 1427 | }, |
1432 | WalkEvent::Leave(e) => { | 1428 | WalkEvent::Leave(e) => { |
1429 | if nested_scope.is_none() { | ||
1430 | if let Some(expr) = ast::Expr::cast(e.clone()) { | ||
1431 | match expr { | ||
1432 | ast::Expr::ReturnExpr(return_expr) if nested_scope.is_none() => { | ||
1433 | let expr = return_expr.expr(); | ||
1434 | if let Some(replacement) = make_rewritten_flow(handler, expr) { | ||
1435 | ted::replace(return_expr.syntax(), replacement.syntax()) | ||
1436 | } | ||
1437 | } | ||
1438 | ast::Expr::BreakExpr(break_expr) if nested_loop.is_none() => { | ||
1439 | let expr = break_expr.expr(); | ||
1440 | if let Some(replacement) = make_rewritten_flow(handler, expr) { | ||
1441 | ted::replace(break_expr.syntax(), replacement.syntax()) | ||
1442 | } | ||
1443 | } | ||
1444 | ast::Expr::ContinueExpr(continue_expr) if nested_loop.is_none() => { | ||
1445 | if let Some(replacement) = make_rewritten_flow(handler, None) { | ||
1446 | ted::replace(continue_expr.syntax(), replacement.syntax()) | ||
1447 | } | ||
1448 | } | ||
1449 | _ => { | ||
1450 | // do nothing | ||
1451 | } | ||
1452 | } | ||
1453 | } | ||
1454 | } | ||
1455 | |||
1433 | if nested_loop.as_ref() == Some(&e) { | 1456 | if nested_loop.as_ref() == Some(&e) { |
1434 | nested_loop = None; | 1457 | nested_loop = None; |
1435 | } | 1458 | } |
1436 | if nested_scope.as_ref() == Some(&e) { | 1459 | if nested_scope.as_ref() == Some(&e) { |
1437 | nested_scope = None; | 1460 | nested_scope = None; |
1438 | } | 1461 | } |
1439 | continue; | ||
1440 | } | 1462 | } |
1441 | }; | 1463 | }; |
1442 | if nested_scope.is_some() { | ||
1443 | continue; | ||
1444 | } | ||
1445 | let expr = match ast::Expr::cast(node) { | ||
1446 | Some(e) => e, | ||
1447 | None => continue, | ||
1448 | }; | ||
1449 | match expr { | ||
1450 | ast::Expr::ReturnExpr(return_expr) if nested_scope.is_none() => { | ||
1451 | let expr = return_expr.expr(); | ||
1452 | if let Some(replacement) = make_rewritten_flow(handler, expr) { | ||
1453 | rewriter.replace_ast(&return_expr.into(), &replacement); | ||
1454 | } | ||
1455 | } | ||
1456 | ast::Expr::BreakExpr(break_expr) if nested_loop.is_none() => { | ||
1457 | let expr = break_expr.expr(); | ||
1458 | if let Some(replacement) = make_rewritten_flow(handler, expr) { | ||
1459 | rewriter.replace_ast(&break_expr.into(), &replacement); | ||
1460 | } | ||
1461 | } | ||
1462 | ast::Expr::ContinueExpr(continue_expr) if nested_loop.is_none() => { | ||
1463 | if let Some(replacement) = make_rewritten_flow(handler, None) { | ||
1464 | rewriter.replace_ast(&continue_expr.into(), &replacement); | ||
1465 | } | ||
1466 | } | ||
1467 | _ => { | ||
1468 | // do nothing | ||
1469 | } | ||
1470 | } | ||
1471 | } | 1464 | } |
1472 | |||
1473 | rewriter.rewrite(syntax) | ||
1474 | } | 1465 | } |
1475 | 1466 | ||
1476 | fn make_rewritten_flow(handler: &FlowHandler, arg_expr: Option<ast::Expr>) -> Option<ast::Expr> { | 1467 | fn make_rewritten_flow(handler: &FlowHandler, arg_expr: Option<ast::Expr>) -> Option<ast::Expr> { |
@@ -1480,16 +1471,16 @@ fn make_rewritten_flow(handler: &FlowHandler, arg_expr: Option<ast::Expr>) -> Op | |||
1480 | FlowHandler::IfOption { .. } => { | 1471 | FlowHandler::IfOption { .. } => { |
1481 | let expr = arg_expr.unwrap_or_else(|| make::expr_tuple(Vec::new())); | 1472 | let expr = arg_expr.unwrap_or_else(|| make::expr_tuple(Vec::new())); |
1482 | let args = make::arg_list(iter::once(expr)); | 1473 | let args = make::arg_list(iter::once(expr)); |
1483 | make::expr_call(make::expr_path(make_path_from_text("Some")), args) | 1474 | make::expr_call(make::expr_path(make::ext::ident_path("Some")), args) |
1484 | } | 1475 | } |
1485 | FlowHandler::MatchOption { .. } => make::expr_path(make_path_from_text("None")), | 1476 | FlowHandler::MatchOption { .. } => make::expr_path(make::ext::ident_path("None")), |
1486 | FlowHandler::MatchResult { .. } => { | 1477 | FlowHandler::MatchResult { .. } => { |
1487 | let expr = arg_expr.unwrap_or_else(|| make::expr_tuple(Vec::new())); | 1478 | let expr = arg_expr.unwrap_or_else(|| make::expr_tuple(Vec::new())); |
1488 | let args = make::arg_list(iter::once(expr)); | 1479 | let args = make::arg_list(iter::once(expr)); |
1489 | make::expr_call(make::expr_path(make_path_from_text("Err")), args) | 1480 | make::expr_call(make::expr_path(make::ext::ident_path("Err")), args) |
1490 | } | 1481 | } |
1491 | }; | 1482 | }; |
1492 | Some(make::expr_return(Some(value))) | 1483 | Some(make::expr_return(Some(value)).clone_for_update()) |
1493 | } | 1484 | } |
1494 | 1485 | ||
1495 | #[cfg(test)] | 1486 | #[cfg(test)] |