diff options
author | Aleksey Kladov <[email protected]> | 2021-05-09 17:51:06 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-05-09 17:55:43 +0100 |
commit | 4f3c0adc5aafea465c71c85f36484da970df1ba2 (patch) | |
tree | 4cb502a6c345c3ecfb4090067ab1de2cfd69ed55 /crates | |
parent | 680a0d54e4d2d474ae41f4f4a95c749495a02883 (diff) |
internal: introduce `ast::make::ext` module with common shortcuts
There's a tension between keeping a well-architectured minimal
orthogonal set of constructs, and providing convenience functions.
Relieve this pressure by introducing an dedicated module for
non-orthogonal shortcuts.
This is inspired by the django.shortcuts module which serves a similar
purpose architecturally.
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ide_assists/src/handlers/early_return.rs | 4 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/expand_glob_import.rs | 3 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/extract_function.rs | 62 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/generate_function.rs | 2 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/move_bounds.rs | 6 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs | 8 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/replace_let_with_if_let.rs | 2 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/replace_unwrap_with_match.rs | 21 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/wrap_return_type_in_result.rs | 4 | ||||
-rw-r--r-- | crates/ide_assists/src/tests/generated.rs | 2 | ||||
-rw-r--r-- | crates/ide_assists/src/utils.rs | 4 | ||||
-rw-r--r-- | crates/ide_db/src/helpers/merge_imports.rs | 2 | ||||
-rw-r--r-- | crates/ide_db/src/ty_filter.rs | 6 | ||||
-rw-r--r-- | crates/syntax/src/ast/make.rs | 95 |
14 files changed, 104 insertions, 117 deletions
diff --git a/crates/ide_assists/src/handlers/early_return.rs b/crates/ide_assists/src/handlers/early_return.rs index c66f8c05d..5eb6a57f0 100644 --- a/crates/ide_assists/src/handlers/early_return.rs +++ b/crates/ide_assists/src/handlers/early_return.rs | |||
@@ -130,9 +130,7 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext) | |||
130 | once(make::ident_pat(make::name("it")).into()), | 130 | once(make::ident_pat(make::name("it")).into()), |
131 | ); | 131 | ); |
132 | let expr = { | 132 | let expr = { |
133 | let name_ref = make::name_ref("it"); | 133 | let path = make::ext::ident_path("it"); |
134 | let segment = make::path_segment(name_ref); | ||
135 | let path = make::path_unqualified(segment); | ||
136 | make::expr_path(path) | 134 | make::expr_path(path) |
137 | }; | 135 | }; |
138 | make::match_arm(once(pat.into()), expr) | 136 | make::match_arm(once(pat.into()), expr) |
diff --git a/crates/ide_assists/src/handlers/expand_glob_import.rs b/crates/ide_assists/src/handlers/expand_glob_import.rs index e3095f26b..da8d245e5 100644 --- a/crates/ide_assists/src/handlers/expand_glob_import.rs +++ b/crates/ide_assists/src/handlers/expand_glob_import.rs | |||
@@ -65,8 +65,7 @@ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Opti | |||
65 | 65 | ||
66 | let names_to_import = find_names_to_import(ctx, refs_in_target, imported_defs); | 66 | let names_to_import = find_names_to_import(ctx, refs_in_target, imported_defs); |
67 | let expanded = make::use_tree_list(names_to_import.iter().map(|n| { | 67 | let expanded = make::use_tree_list(names_to_import.iter().map(|n| { |
68 | let path = | 68 | let path = make::ext::ident_path(&n.to_string()); |
69 | make::path_unqualified(make::path_segment(make::name_ref(&n.to_string()))); | ||
70 | make::use_tree(path, None, None, false) | 69 | make::use_tree(path, None, None, false) |
71 | })) | 70 | })) |
72 | .clone_for_update(); | 71 | .clone_for_update(); |
diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs index 494ef4621..6311afc1f 100644 --- a/crates/ide_assists/src/handlers/extract_function.rs +++ b/crates/ide_assists/src/handlers/extract_function.rs | |||
@@ -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 | }), |
@@ -1483,13 +1471,13 @@ fn make_rewritten_flow(handler: &FlowHandler, arg_expr: Option<ast::Expr>) -> Op | |||
1483 | FlowHandler::IfOption { .. } => { | 1471 | FlowHandler::IfOption { .. } => { |
1484 | 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())); |
1485 | let args = make::arg_list(iter::once(expr)); | 1473 | let args = make::arg_list(iter::once(expr)); |
1486 | 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) |
1487 | } | 1475 | } |
1488 | FlowHandler::MatchOption { .. } => make::expr_path(make_path_from_text("None")), | 1476 | FlowHandler::MatchOption { .. } => make::expr_path(make::ext::ident_path("None")), |
1489 | FlowHandler::MatchResult { .. } => { | 1477 | FlowHandler::MatchResult { .. } => { |
1490 | 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())); |
1491 | let args = make::arg_list(iter::once(expr)); | 1479 | let args = make::arg_list(iter::once(expr)); |
1492 | 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) |
1493 | } | 1481 | } |
1494 | }; | 1482 | }; |
1495 | Some(make::expr_return(Some(value)).clone_for_update()) | 1483 | Some(make::expr_return(Some(value)).clone_for_update()) |
diff --git a/crates/ide_assists/src/handlers/generate_function.rs b/crates/ide_assists/src/handlers/generate_function.rs index 6f95b1a07..bc9fc524b 100644 --- a/crates/ide_assists/src/handlers/generate_function.rs +++ b/crates/ide_assists/src/handlers/generate_function.rs | |||
@@ -175,7 +175,7 @@ impl FunctionBuilder { | |||
175 | } | 175 | } |
176 | 176 | ||
177 | fn render(self) -> FunctionTemplate { | 177 | fn render(self) -> FunctionTemplate { |
178 | let placeholder_expr = make::expr_todo(); | 178 | let placeholder_expr = make::ext::expr_todo(); |
179 | let fn_body = make::block_expr(vec![], Some(placeholder_expr)); | 179 | let fn_body = make::block_expr(vec![], Some(placeholder_expr)); |
180 | let visibility = if self.needs_pub { Some(make::visibility_pub_crate()) } else { None }; | 180 | let visibility = if self.needs_pub { Some(make::visibility_pub_crate()) } else { None }; |
181 | let mut fn_def = make::fn_( | 181 | let mut fn_def = make::fn_( |
diff --git a/crates/ide_assists/src/handlers/move_bounds.rs b/crates/ide_assists/src/handlers/move_bounds.rs index 011a28d44..fa3f76609 100644 --- a/crates/ide_assists/src/handlers/move_bounds.rs +++ b/crates/ide_assists/src/handlers/move_bounds.rs | |||
@@ -63,11 +63,7 @@ pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext | |||
63 | } | 63 | } |
64 | 64 | ||
65 | fn build_predicate(param: ast::TypeParam) -> Option<ast::WherePred> { | 65 | fn build_predicate(param: ast::TypeParam) -> Option<ast::WherePred> { |
66 | let path = { | 66 | let path = make::ext::ident_path(¶m.name()?.syntax().to_string()); |
67 | let name_ref = make::name_ref(¶m.name()?.syntax().to_string()); | ||
68 | let segment = make::path_segment(name_ref); | ||
69 | make::path_unqualified(segment) | ||
70 | }; | ||
71 | let predicate = make::where_pred(path, param.type_bound_list()?.bounds()); | 67 | let predicate = make::where_pred(path, param.type_bound_list()?.bounds()); |
72 | Some(predicate.clone_for_update()) | 68 | Some(predicate.clone_for_update()) |
73 | } | 69 | } |
diff --git a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs index 694d897d1..10d9cec31 100644 --- a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs | |||
@@ -84,7 +84,7 @@ pub(crate) fn replace_derive_with_manual_impl( | |||
84 | add_assist(acc, ctx, &attr, &args, &trait_path, Some(trait_), &adt)?; | 84 | add_assist(acc, ctx, &attr, &args, &trait_path, Some(trait_), &adt)?; |
85 | } | 85 | } |
86 | if no_traits_found { | 86 | if no_traits_found { |
87 | let trait_path = make::path_unqualified(make::path_segment(make::name_ref(trait_name))); | 87 | let trait_path = make::ext::ident_path(trait_name); |
88 | add_assist(acc, ctx, &attr, &args, &trait_path, None, &adt)?; | 88 | add_assist(acc, ctx, &attr, &args, &trait_path, None, &adt)?; |
89 | } | 89 | } |
90 | Some(()) | 90 | Some(()) |
@@ -159,10 +159,8 @@ fn impl_def_from_trait( | |||
159 | if trait_items.is_empty() { | 159 | if trait_items.is_empty() { |
160 | return None; | 160 | return None; |
161 | } | 161 | } |
162 | let impl_def = make::impl_trait( | 162 | let impl_def = |
163 | trait_path.clone(), | 163 | make::impl_trait(trait_path.clone(), make::ext::ident_path(&annotated_name.text())); |
164 | make::path_unqualified(make::path_segment(make::name_ref(&annotated_name.text()))), | ||
165 | ); | ||
166 | let (impl_def, first_assoc_item) = | 164 | let (impl_def, first_assoc_item) = |
167 | add_trait_assoc_items_to_impl(sema, trait_items, trait_, impl_def, target_scope); | 165 | add_trait_assoc_items_to_impl(sema, trait_items, trait_, impl_def, target_scope); |
168 | Some((impl_def, first_assoc_item)) | 166 | Some((impl_def, first_assoc_item)) |
diff --git a/crates/ide_assists/src/handlers/replace_let_with_if_let.rs b/crates/ide_assists/src/handlers/replace_let_with_if_let.rs index be7e724b5..f811234c0 100644 --- a/crates/ide_assists/src/handlers/replace_let_with_if_let.rs +++ b/crates/ide_assists/src/handlers/replace_let_with_if_let.rs | |||
@@ -53,7 +53,7 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext) -> | |||
53 | let with_placeholder: ast::Pat = match happy_variant { | 53 | let with_placeholder: ast::Pat = match happy_variant { |
54 | None => make::wildcard_pat().into(), | 54 | None => make::wildcard_pat().into(), |
55 | Some(var_name) => make::tuple_struct_pat( | 55 | Some(var_name) => make::tuple_struct_pat( |
56 | make::path_unqualified(make::path_segment(make::name_ref(var_name))), | 56 | make::ext::ident_path(var_name), |
57 | once(make::wildcard_pat().into()), | 57 | once(make::wildcard_pat().into()), |
58 | ) | 58 | ) |
59 | .into(), | 59 | .into(), |
diff --git a/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs b/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs index a986a6ae8..0fec961b4 100644 --- a/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs +++ b/crates/ide_assists/src/handlers/replace_unwrap_with_match.rs | |||
@@ -32,7 +32,7 @@ use ide_db::ty_filter::TryEnum; | |||
32 | // fn main() { | 32 | // fn main() { |
33 | // let x: Result<i32, i32> = Result::Ok(92); | 33 | // let x: Result<i32, i32> = Result::Ok(92); |
34 | // let y = match x { | 34 | // let y = match x { |
35 | // Ok(a) => a, | 35 | // Ok(it) => it, |
36 | // $0_ => unreachable!(), | 36 | // $0_ => unreachable!(), |
37 | // }; | 37 | // }; |
38 | // } | 38 | // } |
@@ -52,16 +52,17 @@ pub(crate) fn replace_unwrap_with_match(acc: &mut Assists, ctx: &AssistContext) | |||
52 | "Replace unwrap with match", | 52 | "Replace unwrap with match", |
53 | target, | 53 | target, |
54 | |builder| { | 54 | |builder| { |
55 | let ok_path = make::path_unqualified(make::path_segment(make::name_ref(happy_variant))); | 55 | let ok_path = make::ext::ident_path(happy_variant); |
56 | let it = make::ident_pat(make::name("a")).into(); | 56 | let it = make::ident_pat(make::name("it")).into(); |
57 | let ok_tuple = make::tuple_struct_pat(ok_path, iter::once(it)).into(); | 57 | let ok_tuple = make::tuple_struct_pat(ok_path, iter::once(it)).into(); |
58 | 58 | ||
59 | let bind_path = make::path_unqualified(make::path_segment(make::name_ref("a"))); | 59 | let bind_path = make::ext::ident_path("it"); |
60 | let ok_arm = make::match_arm(iter::once(ok_tuple), make::expr_path(bind_path)); | 60 | let ok_arm = make::match_arm(iter::once(ok_tuple), make::expr_path(bind_path)); |
61 | 61 | ||
62 | let unreachable_call = make::expr_unreachable(); | 62 | let err_arm = make::match_arm( |
63 | let err_arm = | 63 | iter::once(make::wildcard_pat().into()), |
64 | make::match_arm(iter::once(make::wildcard_pat().into()), unreachable_call); | 64 | make::ext::expr_unreachable(), |
65 | ); | ||
65 | 66 | ||
66 | let match_arm_list = make::match_arm_list(vec![ok_arm, err_arm]); | 67 | let match_arm_list = make::match_arm_list(vec![ok_arm, err_arm]); |
67 | let match_expr = make::expr_match(caller.clone(), match_arm_list) | 68 | let match_expr = make::expr_match(caller.clone(), match_arm_list) |
@@ -110,7 +111,7 @@ fn i<T>(a: T) -> T { a } | |||
110 | fn main() { | 111 | fn main() { |
111 | let x: Result<i32, i32> = Result::Ok(92); | 112 | let x: Result<i32, i32> = Result::Ok(92); |
112 | let y = match i(x) { | 113 | let y = match i(x) { |
113 | Ok(a) => a, | 114 | Ok(it) => it, |
114 | $0_ => unreachable!(), | 115 | $0_ => unreachable!(), |
115 | }; | 116 | }; |
116 | } | 117 | } |
@@ -136,7 +137,7 @@ fn i<T>(a: T) -> T { a } | |||
136 | fn main() { | 137 | fn main() { |
137 | let x = Option::Some(92); | 138 | let x = Option::Some(92); |
138 | let y = match i(x) { | 139 | let y = match i(x) { |
139 | Some(a) => a, | 140 | Some(it) => it, |
140 | $0_ => unreachable!(), | 141 | $0_ => unreachable!(), |
141 | }; | 142 | }; |
142 | } | 143 | } |
@@ -162,7 +163,7 @@ fn i<T>(a: T) -> T { a } | |||
162 | fn main() { | 163 | fn main() { |
163 | let x: Result<i32, i32> = Result::Ok(92); | 164 | let x: Result<i32, i32> = Result::Ok(92); |
164 | let y = match i(x) { | 165 | let y = match i(x) { |
165 | Ok(a) => a, | 166 | Ok(it) => it, |
166 | $0_ => unreachable!(), | 167 | $0_ => unreachable!(), |
167 | }.count_zeroes(); | 168 | }.count_zeroes(); |
168 | } | 169 | } |
diff --git a/crates/ide_assists/src/handlers/wrap_return_type_in_result.rs b/crates/ide_assists/src/handlers/wrap_return_type_in_result.rs index e838630ea..2f1da82c7 100644 --- a/crates/ide_assists/src/handlers/wrap_return_type_in_result.rs +++ b/crates/ide_assists/src/handlers/wrap_return_type_in_result.rs | |||
@@ -54,9 +54,7 @@ pub(crate) fn wrap_return_type_in_result(acc: &mut Assists, ctx: &AssistContext) | |||
54 | 54 | ||
55 | for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { | 55 | for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { |
56 | let ok_wrapped = make::expr_call( | 56 | let ok_wrapped = make::expr_call( |
57 | make::expr_path(make::path_unqualified(make::path_segment(make::name_ref( | 57 | make::expr_path(make::ext::ident_path("Ok")), |
58 | "Ok", | ||
59 | )))), | ||
60 | make::arg_list(iter::once(ret_expr_arg.clone())), | 58 | make::arg_list(iter::once(ret_expr_arg.clone())), |
61 | ); | 59 | ); |
62 | builder.replace_ast(ret_expr_arg, ok_wrapped); | 60 | builder.replace_ast(ret_expr_arg, ok_wrapped); |
diff --git a/crates/ide_assists/src/tests/generated.rs b/crates/ide_assists/src/tests/generated.rs index 59bcef8fb..49c1a9776 100644 --- a/crates/ide_assists/src/tests/generated.rs +++ b/crates/ide_assists/src/tests/generated.rs | |||
@@ -1531,7 +1531,7 @@ enum Result<T, E> { Ok(T), Err(E) } | |||
1531 | fn main() { | 1531 | fn main() { |
1532 | let x: Result<i32, i32> = Result::Ok(92); | 1532 | let x: Result<i32, i32> = Result::Ok(92); |
1533 | let y = match x { | 1533 | let y = match x { |
1534 | Ok(a) => a, | 1534 | Ok(it) => it, |
1535 | $0_ => unreachable!(), | 1535 | $0_ => unreachable!(), |
1536 | }; | 1536 | }; |
1537 | } | 1537 | } |
diff --git a/crates/ide_assists/src/utils.rs b/crates/ide_assists/src/utils.rs index 5a90ad715..0dcf20c61 100644 --- a/crates/ide_assists/src/utils.rs +++ b/crates/ide_assists/src/utils.rs | |||
@@ -159,8 +159,8 @@ pub fn add_trait_assoc_items_to_impl( | |||
159 | match fn_def.body() { | 159 | match fn_def.body() { |
160 | Some(_) => fn_def, | 160 | Some(_) => fn_def, |
161 | None => { | 161 | None => { |
162 | let body = | 162 | let body = make::block_expr(None, Some(make::ext::expr_todo())) |
163 | make::block_expr(None, Some(make::expr_todo())).indent(edit::IndentLevel(1)); | 163 | .indent(edit::IndentLevel(1)); |
164 | fn_def.with_body(body) | 164 | fn_def.with_body(body) |
165 | } | 165 | } |
166 | } | 166 | } |
diff --git a/crates/ide_db/src/helpers/merge_imports.rs b/crates/ide_db/src/helpers/merge_imports.rs index 3f5bbef7f..148297279 100644 --- a/crates/ide_db/src/helpers/merge_imports.rs +++ b/crates/ide_db/src/helpers/merge_imports.rs | |||
@@ -137,7 +137,7 @@ fn recursive_merge( | |||
137 | None, | 137 | None, |
138 | false, | 138 | false, |
139 | ); | 139 | ); |
140 | use_trees.insert(idx, make::glob_use_tree()); | 140 | use_trees.insert(idx, make::use_tree_glob()); |
141 | continue; | 141 | continue; |
142 | } | 142 | } |
143 | 143 | ||
diff --git a/crates/ide_db/src/ty_filter.rs b/crates/ide_db/src/ty_filter.rs index 988ecd060..00678bf3e 100644 --- a/crates/ide_db/src/ty_filter.rs +++ b/crates/ide_db/src/ty_filter.rs | |||
@@ -43,7 +43,7 @@ impl TryEnum { | |||
43 | pub fn sad_pattern(self) -> ast::Pat { | 43 | pub fn sad_pattern(self) -> ast::Pat { |
44 | match self { | 44 | match self { |
45 | TryEnum::Result => make::tuple_struct_pat( | 45 | TryEnum::Result => make::tuple_struct_pat( |
46 | make::path_unqualified(make::path_segment(make::name_ref("Err"))), | 46 | make::ext::ident_path("Err"), |
47 | iter::once(make::wildcard_pat().into()), | 47 | iter::once(make::wildcard_pat().into()), |
48 | ) | 48 | ) |
49 | .into(), | 49 | .into(), |
@@ -54,12 +54,12 @@ impl TryEnum { | |||
54 | pub fn happy_pattern(self) -> ast::Pat { | 54 | pub fn happy_pattern(self) -> ast::Pat { |
55 | match self { | 55 | match self { |
56 | TryEnum::Result => make::tuple_struct_pat( | 56 | TryEnum::Result => make::tuple_struct_pat( |
57 | make::path_unqualified(make::path_segment(make::name_ref("Ok"))), | 57 | make::ext::ident_path("Ok"), |
58 | iter::once(make::wildcard_pat().into()), | 58 | iter::once(make::wildcard_pat().into()), |
59 | ) | 59 | ) |
60 | .into(), | 60 | .into(), |
61 | TryEnum::Option => make::tuple_struct_pat( | 61 | TryEnum::Option => make::tuple_struct_pat( |
62 | make::path_unqualified(make::path_segment(make::name_ref("Some"))), | 62 | make::ext::ident_path("Some"), |
63 | iter::once(make::wildcard_pat().into()), | 63 | iter::once(make::wildcard_pat().into()), |
64 | ) | 64 | ) |
65 | .into(), | 65 | .into(), |
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index c39e248ce..a378b1d37 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | //! | 3 | //! |
4 | //! Note that all functions here intended to be stupid constructors, which just | 4 | //! Note that all functions here intended to be stupid constructors, which just |
5 | //! assemble a finish node from immediate children. If you want to do something | 5 | //! assemble a finish node from immediate children. If you want to do something |
6 | //! smarter than that, it probably doesn't belong in this module. | 6 | //! smarter than that, it belongs to the `ext` submodule. |
7 | //! | 7 | //! |
8 | //! Keep in mind that `from_text` functions should be kept private. The public | 8 | //! Keep in mind that `from_text` functions should be kept private. The public |
9 | //! API should require to assemble every node piecewise. The trick of | 9 | //! API should require to assemble every node piecewise. The trick of |
@@ -14,13 +14,49 @@ use stdx::{format_to, never}; | |||
14 | 14 | ||
15 | use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken}; | 15 | use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken}; |
16 | 16 | ||
17 | /// While the parent module defines basic atomic "constructors", the `ext` | ||
18 | /// module defines shortcuts for common things. | ||
19 | /// | ||
20 | /// It's named `ext` rather than `shortcuts` just to keep it short. | ||
21 | pub mod ext { | ||
22 | use super::*; | ||
23 | |||
24 | pub fn ident_path(ident: &str) -> ast::Path { | ||
25 | path_unqualified(path_segment(name_ref(ident))) | ||
26 | } | ||
27 | |||
28 | pub fn expr_unreachable() -> ast::Expr { | ||
29 | expr_from_text("unreachable!()") | ||
30 | } | ||
31 | pub fn expr_todo() -> ast::Expr { | ||
32 | expr_from_text("todo!()") | ||
33 | } | ||
34 | |||
35 | pub fn ty_bool() -> ast::Type { | ||
36 | ty_path(ident_path("bool")) | ||
37 | } | ||
38 | pub fn ty_option(t: ast::Type) -> ast::Type { | ||
39 | ty_from_text(&format!("Option<{}>", t)) | ||
40 | } | ||
41 | pub fn ty_result(t: ast::Type, e: ast::Type) -> ast::Type { | ||
42 | ty_from_text(&format!("Result<{}, {}>", t, e)) | ||
43 | } | ||
44 | } | ||
45 | |||
17 | pub fn name(text: &str) -> ast::Name { | 46 | pub fn name(text: &str) -> ast::Name { |
18 | ast_from_text(&format!("mod {}{};", raw_ident_esc(text), text)) | 47 | ast_from_text(&format!("mod {}{};", raw_ident_esc(text), text)) |
19 | } | 48 | } |
20 | |||
21 | pub fn name_ref(text: &str) -> ast::NameRef { | 49 | pub fn name_ref(text: &str) -> ast::NameRef { |
22 | ast_from_text(&format!("fn f() {{ {}{}; }}", raw_ident_esc(text), text)) | 50 | ast_from_text(&format!("fn f() {{ {}{}; }}", raw_ident_esc(text), text)) |
23 | } | 51 | } |
52 | fn raw_ident_esc(ident: &str) -> &'static str { | ||
53 | let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some(); | ||
54 | if is_keyword && !matches!(ident, "self" | "crate" | "super" | "Self") { | ||
55 | "r#" | ||
56 | } else { | ||
57 | "" | ||
58 | } | ||
59 | } | ||
24 | 60 | ||
25 | pub fn lifetime(text: &str) -> ast::Lifetime { | 61 | pub fn lifetime(text: &str) -> ast::Lifetime { |
26 | let mut text = text; | 62 | let mut text = text; |
@@ -32,15 +68,6 @@ pub fn lifetime(text: &str) -> ast::Lifetime { | |||
32 | ast_from_text(&format!("fn f<{}>() {{ }}", text)) | 68 | ast_from_text(&format!("fn f<{}>() {{ }}", text)) |
33 | } | 69 | } |
34 | 70 | ||
35 | fn raw_ident_esc(ident: &str) -> &'static str { | ||
36 | let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some(); | ||
37 | if is_keyword && !matches!(ident, "self" | "crate" | "super" | "Self") { | ||
38 | "r#" | ||
39 | } else { | ||
40 | "" | ||
41 | } | ||
42 | } | ||
43 | |||
44 | // FIXME: replace stringly-typed constructor with a family of typed ctors, a-la | 71 | // FIXME: replace stringly-typed constructor with a family of typed ctors, a-la |
45 | // `expr_xxx`. | 72 | // `expr_xxx`. |
46 | pub fn ty(text: &str) -> ast::Type { | 73 | pub fn ty(text: &str) -> ast::Type { |
@@ -49,9 +76,6 @@ pub fn ty(text: &str) -> ast::Type { | |||
49 | pub fn ty_unit() -> ast::Type { | 76 | pub fn ty_unit() -> ast::Type { |
50 | ty_from_text("()") | 77 | ty_from_text("()") |
51 | } | 78 | } |
52 | pub fn ty_bool() -> ast::Type { | ||
53 | ty_path(path_unqualified(path_segment(name_ref("bool")))) | ||
54 | } | ||
55 | pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type { | 79 | pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type { |
56 | let mut count: usize = 0; | 80 | let mut count: usize = 0; |
57 | let mut contents = types.into_iter().inspect(|_| count += 1).join(", "); | 81 | let mut contents = types.into_iter().inspect(|_| count += 1).join(", "); |
@@ -61,11 +85,6 @@ pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type { | |||
61 | 85 | ||
62 | ty_from_text(&format!("({})", contents)) | 86 | ty_from_text(&format!("({})", contents)) |
63 | } | 87 | } |
64 | // FIXME: handle path to type | ||
65 | pub fn ty_generic(name: ast::NameRef, types: impl IntoIterator<Item = ast::Type>) -> ast::Type { | ||
66 | let contents = types.into_iter().join(", "); | ||
67 | ty_from_text(&format!("{}<{}>", name, contents)) | ||
68 | } | ||
69 | pub fn ty_ref(target: ast::Type, exclusive: bool) -> ast::Type { | 88 | pub fn ty_ref(target: ast::Type, exclusive: bool) -> ast::Type { |
70 | ty_from_text(&if exclusive { format!("&mut {}", target) } else { format!("&{}", target) }) | 89 | ty_from_text(&if exclusive { format!("&mut {}", target) } else { format!("&{}", target) }) |
71 | } | 90 | } |
@@ -107,7 +126,7 @@ pub fn path_unqualified(segment: ast::PathSegment) -> ast::Path { | |||
107 | pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path { | 126 | pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path { |
108 | ast_from_text(&format!("{}::{}", qual, segment)) | 127 | ast_from_text(&format!("{}::{}", qual, segment)) |
109 | } | 128 | } |
110 | 129 | // FIXME: path concatenation operation doesn't make sense as AST op. | |
111 | pub fn path_concat(first: ast::Path, second: ast::Path) -> ast::Path { | 130 | pub fn path_concat(first: ast::Path, second: ast::Path) -> ast::Path { |
112 | ast_from_text(&format!("{}::{}", first, second)) | 131 | ast_from_text(&format!("{}::{}", first, second)) |
113 | } | 132 | } |
@@ -123,15 +142,14 @@ pub fn path_from_segments( | |||
123 | format!("use {};", segments) | 142 | format!("use {};", segments) |
124 | }) | 143 | }) |
125 | } | 144 | } |
126 | 145 | // FIXME: should not be pub | |
127 | pub fn path_from_text(text: &str) -> ast::Path { | 146 | pub fn path_from_text(text: &str) -> ast::Path { |
128 | ast_from_text(&format!("fn main() {{ let test = {}; }}", text)) | 147 | ast_from_text(&format!("fn main() {{ let test = {}; }}", text)) |
129 | } | 148 | } |
130 | 149 | ||
131 | pub fn glob_use_tree() -> ast::UseTree { | 150 | pub fn use_tree_glob() -> ast::UseTree { |
132 | ast_from_text("use *;") | 151 | ast_from_text("use *;") |
133 | } | 152 | } |
134 | |||
135 | pub fn use_tree( | 153 | pub fn use_tree( |
136 | path: ast::Path, | 154 | path: ast::Path, |
137 | use_tree_list: Option<ast::UseTreeList>, | 155 | use_tree_list: Option<ast::UseTreeList>, |
@@ -226,15 +244,6 @@ pub fn expr_literal(text: &str) -> ast::Literal { | |||
226 | pub fn expr_empty_block() -> ast::Expr { | 244 | pub fn expr_empty_block() -> ast::Expr { |
227 | expr_from_text("{}") | 245 | expr_from_text("{}") |
228 | } | 246 | } |
229 | pub fn expr_unimplemented() -> ast::Expr { | ||
230 | expr_from_text("unimplemented!()") | ||
231 | } | ||
232 | pub fn expr_unreachable() -> ast::Expr { | ||
233 | expr_from_text("unreachable!()") | ||
234 | } | ||
235 | pub fn expr_todo() -> ast::Expr { | ||
236 | expr_from_text("todo!()") | ||
237 | } | ||
238 | pub fn expr_path(path: ast::Path) -> ast::Expr { | 247 | pub fn expr_path(path: ast::Path) -> ast::Expr { |
239 | expr_from_text(&path.to_string()) | 248 | expr_from_text(&path.to_string()) |
240 | } | 249 | } |
@@ -463,17 +472,6 @@ pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt { | |||
463 | ast_from_text(&format!("fn f() {{ {}{} (); }}", expr, semi)) | 472 | ast_from_text(&format!("fn f() {{ {}{} (); }}", expr, semi)) |
464 | } | 473 | } |
465 | 474 | ||
466 | pub fn token(kind: SyntaxKind) -> SyntaxToken { | ||
467 | tokens::SOURCE_FILE | ||
468 | .tree() | ||
469 | .syntax() | ||
470 | .clone_for_update() | ||
471 | .descendants_with_tokens() | ||
472 | .filter_map(|it| it.into_token()) | ||
473 | .find(|it| it.kind() == kind) | ||
474 | .unwrap_or_else(|| panic!("unhandled token: {:?}", kind)) | ||
475 | } | ||
476 | |||
477 | pub fn param(pat: ast::Pat, ty: ast::Type) -> ast::Param { | 475 | pub fn param(pat: ast::Pat, ty: ast::Type) -> ast::Param { |
478 | ast_from_text(&format!("fn f({}: {}) {{ }}", pat, ty)) | 476 | ast_from_text(&format!("fn f({}: {}) {{ }}", pat, ty)) |
479 | } | 477 | } |
@@ -611,6 +609,17 @@ fn unroot(n: SyntaxNode) -> SyntaxNode { | |||
611 | SyntaxNode::new_root(n.green().into()) | 609 | SyntaxNode::new_root(n.green().into()) |
612 | } | 610 | } |
613 | 611 | ||
612 | pub fn token(kind: SyntaxKind) -> SyntaxToken { | ||
613 | tokens::SOURCE_FILE | ||
614 | .tree() | ||
615 | .syntax() | ||
616 | .clone_for_update() | ||
617 | .descendants_with_tokens() | ||
618 | .filter_map(|it| it.into_token()) | ||
619 | .find(|it| it.kind() == kind) | ||
620 | .unwrap_or_else(|| panic!("unhandled token: {:?}", kind)) | ||
621 | } | ||
622 | |||
614 | pub mod tokens { | 623 | pub mod tokens { |
615 | use once_cell::sync::Lazy; | 624 | use once_cell::sync::Lazy; |
616 | 625 | ||