Merge #8783
8783: internal: introduce `ast::make::ext` module with common shortcuts r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
75a5c0a534
@ -130,9 +130,7 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
|
|||||||
once(make::ident_pat(make::name("it")).into()),
|
once(make::ident_pat(make::name("it")).into()),
|
||||||
);
|
);
|
||||||
let expr = {
|
let expr = {
|
||||||
let name_ref = make::name_ref("it");
|
let path = make::ext::ident_path("it");
|
||||||
let segment = make::path_segment(name_ref);
|
|
||||||
let path = make::path_unqualified(segment);
|
|
||||||
make::expr_path(path)
|
make::expr_path(path)
|
||||||
};
|
};
|
||||||
make::match_arm(once(pat.into()), expr)
|
make::match_arm(once(pat.into()), expr)
|
||||||
|
@ -65,8 +65,7 @@ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Opti
|
|||||||
|
|
||||||
let names_to_import = find_names_to_import(ctx, refs_in_target, imported_defs);
|
let names_to_import = find_names_to_import(ctx, refs_in_target, imported_defs);
|
||||||
let expanded = make::use_tree_list(names_to_import.iter().map(|n| {
|
let expanded = make::use_tree_list(names_to_import.iter().map(|n| {
|
||||||
let path =
|
let path = make::ext::ident_path(&n.to_string());
|
||||||
make::path_unqualified(make::path_segment(make::name_ref(&n.to_string())));
|
|
||||||
make::use_tree(path, None, None, false)
|
make::use_tree(path, None, None, false)
|
||||||
}))
|
}))
|
||||||
.clone_for_update();
|
.clone_for_update();
|
||||||
|
@ -956,10 +956,10 @@ fn format_replacement(ctx: &AssistContext, fun: &Function, indent: IndentLevel)
|
|||||||
let args = fun.params.iter().map(|param| param.to_arg(ctx));
|
let args = fun.params.iter().map(|param| param.to_arg(ctx));
|
||||||
let args = make::arg_list(args);
|
let args = make::arg_list(args);
|
||||||
let call_expr = if fun.self_param.is_some() {
|
let call_expr = if fun.self_param.is_some() {
|
||||||
let self_arg = make::expr_path(make_path_from_text("self"));
|
let self_arg = make::expr_path(make::ext::ident_path("self"));
|
||||||
make::expr_method_call(self_arg, &fun.name, args)
|
make::expr_method_call(self_arg, &fun.name, args)
|
||||||
} else {
|
} else {
|
||||||
let func = make::expr_path(make_path_from_text(&fun.name));
|
let func = make::expr_path(make::ext::ident_path(&fun.name));
|
||||||
make::expr_call(func, args)
|
make::expr_call(func, args)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1054,11 +1054,11 @@ fn make_call_expr(&self, call_expr: ast::Expr) -> ast::Expr {
|
|||||||
make::expr_if(condition, block, None)
|
make::expr_if(condition, block, None)
|
||||||
}
|
}
|
||||||
FlowHandler::IfOption { action } => {
|
FlowHandler::IfOption { action } => {
|
||||||
let path = make_path_from_text("Some");
|
let path = make::ext::ident_path("Some");
|
||||||
let value_pat = make::ident_pat(make::name("value"));
|
let value_pat = make::ident_pat(make::name("value"));
|
||||||
let pattern = make::tuple_struct_pat(path, iter::once(value_pat.into()));
|
let pattern = make::tuple_struct_pat(path, iter::once(value_pat.into()));
|
||||||
let cond = make::condition(call_expr, Some(pattern.into()));
|
let cond = make::condition(call_expr, Some(pattern.into()));
|
||||||
let value = make::expr_path(make_path_from_text("value"));
|
let value = make::expr_path(make::ext::ident_path("value"));
|
||||||
let action_expr = action.make_result_handler(Some(value));
|
let action_expr = action.make_result_handler(Some(value));
|
||||||
let action_stmt = make::expr_stmt(action_expr);
|
let action_stmt = make::expr_stmt(action_expr);
|
||||||
let then = make::block_expr(iter::once(action_stmt.into()), None);
|
let then = make::block_expr(iter::once(action_stmt.into()), None);
|
||||||
@ -1068,14 +1068,14 @@ fn make_call_expr(&self, call_expr: ast::Expr) -> ast::Expr {
|
|||||||
let some_name = "value";
|
let some_name = "value";
|
||||||
|
|
||||||
let some_arm = {
|
let some_arm = {
|
||||||
let path = make_path_from_text("Some");
|
let path = make::ext::ident_path("Some");
|
||||||
let value_pat = make::ident_pat(make::name(some_name));
|
let value_pat = make::ident_pat(make::name(some_name));
|
||||||
let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
|
let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
|
||||||
let value = make::expr_path(make_path_from_text(some_name));
|
let value = make::expr_path(make::ext::ident_path(some_name));
|
||||||
make::match_arm(iter::once(pat.into()), value)
|
make::match_arm(iter::once(pat.into()), value)
|
||||||
};
|
};
|
||||||
let none_arm = {
|
let none_arm = {
|
||||||
let path = make_path_from_text("None");
|
let path = make::ext::ident_path("None");
|
||||||
let pat = make::path_pat(path);
|
let pat = make::path_pat(path);
|
||||||
make::match_arm(iter::once(pat), none.make_result_handler(None))
|
make::match_arm(iter::once(pat), none.make_result_handler(None))
|
||||||
};
|
};
|
||||||
@ -1087,17 +1087,17 @@ fn make_call_expr(&self, call_expr: ast::Expr) -> ast::Expr {
|
|||||||
let err_name = "value";
|
let err_name = "value";
|
||||||
|
|
||||||
let ok_arm = {
|
let ok_arm = {
|
||||||
let path = make_path_from_text("Ok");
|
let path = make::ext::ident_path("Ok");
|
||||||
let value_pat = make::ident_pat(make::name(ok_name));
|
let value_pat = make::ident_pat(make::name(ok_name));
|
||||||
let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
|
let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
|
||||||
let value = make::expr_path(make_path_from_text(ok_name));
|
let value = make::expr_path(make::ext::ident_path(ok_name));
|
||||||
make::match_arm(iter::once(pat.into()), value)
|
make::match_arm(iter::once(pat.into()), value)
|
||||||
};
|
};
|
||||||
let err_arm = {
|
let err_arm = {
|
||||||
let path = make_path_from_text("Err");
|
let path = make::ext::ident_path("Err");
|
||||||
let value_pat = make::ident_pat(make::name(err_name));
|
let value_pat = make::ident_pat(make::name(err_name));
|
||||||
let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
|
let pat = make::tuple_struct_pat(path, iter::once(value_pat.into()));
|
||||||
let value = make::expr_path(make_path_from_text(err_name));
|
let value = make::expr_path(make::ext::ident_path(err_name));
|
||||||
make::match_arm(iter::once(pat.into()), err.make_result_handler(Some(value)))
|
make::match_arm(iter::once(pat.into()), err.make_result_handler(Some(value)))
|
||||||
};
|
};
|
||||||
let arms = make::match_arm_list(vec![ok_arm, err_arm]);
|
let arms = make::match_arm_list(vec![ok_arm, err_arm]);
|
||||||
@ -1107,13 +1107,9 @@ fn make_call_expr(&self, call_expr: ast::Expr) -> ast::Expr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_path_from_text(text: &str) -> ast::Path {
|
|
||||||
make::path_unqualified(make::path_segment(make::name_ref(text)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn path_expr_from_local(ctx: &AssistContext, var: Local) -> ast::Expr {
|
fn path_expr_from_local(ctx: &AssistContext, var: Local) -> ast::Expr {
|
||||||
let name = var.name(ctx.db()).unwrap().to_string();
|
let name = var.name(ctx.db()).unwrap().to_string();
|
||||||
make::expr_path(make_path_from_text(&name))
|
make::expr_path(make::ext::ident_path(&name))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_function(
|
fn format_function(
|
||||||
@ -1179,7 +1175,7 @@ fn make_ret_ty(ctx: &AssistContext, module: hir::Module, fun: &Function) -> Opti
|
|||||||
fun_ty.make_ty(ctx, module)
|
fun_ty.make_ty(ctx, module)
|
||||||
}
|
}
|
||||||
FlowHandler::Try { kind: TryKind::Option } => {
|
FlowHandler::Try { kind: TryKind::Option } => {
|
||||||
make::ty_generic(make::name_ref("Option"), iter::once(fun_ty.make_ty(ctx, module)))
|
make::ext::ty_option(fun_ty.make_ty(ctx, module))
|
||||||
}
|
}
|
||||||
FlowHandler::Try { kind: TryKind::Result { ty: parent_ret_ty } } => {
|
FlowHandler::Try { kind: TryKind::Result { ty: parent_ret_ty } } => {
|
||||||
let handler_ty = parent_ret_ty
|
let handler_ty = parent_ret_ty
|
||||||
@ -1187,29 +1183,21 @@ fn make_ret_ty(ctx: &AssistContext, module: hir::Module, fun: &Function) -> Opti
|
|||||||
.nth(1)
|
.nth(1)
|
||||||
.map(|ty| make_ty(&ty, ctx, module))
|
.map(|ty| make_ty(&ty, ctx, module))
|
||||||
.unwrap_or_else(make::ty_unit);
|
.unwrap_or_else(make::ty_unit);
|
||||||
make::ty_generic(
|
make::ext::ty_result(fun_ty.make_ty(ctx, module), handler_ty)
|
||||||
make::name_ref("Result"),
|
|
||||||
vec![fun_ty.make_ty(ctx, module), handler_ty],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
FlowHandler::If { .. } => make::ty_bool(),
|
FlowHandler::If { .. } => make::ext::ty_bool(),
|
||||||
FlowHandler::IfOption { action } => {
|
FlowHandler::IfOption { action } => {
|
||||||
let handler_ty = action
|
let handler_ty = action
|
||||||
.expr_ty(ctx)
|
.expr_ty(ctx)
|
||||||
.map(|ty| make_ty(&ty, ctx, module))
|
.map(|ty| make_ty(&ty, ctx, module))
|
||||||
.unwrap_or_else(make::ty_unit);
|
.unwrap_or_else(make::ty_unit);
|
||||||
make::ty_generic(make::name_ref("Option"), iter::once(handler_ty))
|
make::ext::ty_option(handler_ty)
|
||||||
}
|
|
||||||
FlowHandler::MatchOption { .. } => {
|
|
||||||
make::ty_generic(make::name_ref("Option"), iter::once(fun_ty.make_ty(ctx, module)))
|
|
||||||
}
|
}
|
||||||
|
FlowHandler::MatchOption { .. } => make::ext::ty_option(fun_ty.make_ty(ctx, module)),
|
||||||
FlowHandler::MatchResult { err } => {
|
FlowHandler::MatchResult { err } => {
|
||||||
let handler_ty =
|
let handler_ty =
|
||||||
err.expr_ty(ctx).map(|ty| make_ty(&ty, ctx, module)).unwrap_or_else(make::ty_unit);
|
err.expr_ty(ctx).map(|ty| make_ty(&ty, ctx, module)).unwrap_or_else(make::ty_unit);
|
||||||
make::ty_generic(
|
make::ext::ty_result(fun_ty.make_ty(ctx, module), handler_ty)
|
||||||
make::name_ref("Result"),
|
|
||||||
vec![fun_ty.make_ty(ctx, module), handler_ty],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Some(make::ret_type(ret_ty))
|
Some(make::ret_type(ret_ty))
|
||||||
@ -1296,7 +1284,7 @@ fn make_body(
|
|||||||
TryKind::Option => "Some",
|
TryKind::Option => "Some",
|
||||||
TryKind::Result { .. } => "Ok",
|
TryKind::Result { .. } => "Ok",
|
||||||
};
|
};
|
||||||
let func = make::expr_path(make_path_from_text(constructor));
|
let func = make::expr_path(make::ext::ident_path(constructor));
|
||||||
let args = make::arg_list(iter::once(tail_expr));
|
let args = make::arg_list(iter::once(tail_expr));
|
||||||
make::expr_call(func, args)
|
make::expr_call(func, args)
|
||||||
})
|
})
|
||||||
@ -1306,16 +1294,16 @@ fn make_body(
|
|||||||
with_tail_expr(block, lit_false.into())
|
with_tail_expr(block, lit_false.into())
|
||||||
}
|
}
|
||||||
FlowHandler::IfOption { .. } => {
|
FlowHandler::IfOption { .. } => {
|
||||||
let none = make::expr_path(make_path_from_text("None"));
|
let none = make::expr_path(make::ext::ident_path("None"));
|
||||||
with_tail_expr(block, none)
|
with_tail_expr(block, none)
|
||||||
}
|
}
|
||||||
FlowHandler::MatchOption { .. } => map_tail_expr(block, |tail_expr| {
|
FlowHandler::MatchOption { .. } => map_tail_expr(block, |tail_expr| {
|
||||||
let some = make::expr_path(make_path_from_text("Some"));
|
let some = make::expr_path(make::ext::ident_path("Some"));
|
||||||
let args = make::arg_list(iter::once(tail_expr));
|
let args = make::arg_list(iter::once(tail_expr));
|
||||||
make::expr_call(some, args)
|
make::expr_call(some, args)
|
||||||
}),
|
}),
|
||||||
FlowHandler::MatchResult { .. } => map_tail_expr(block, |tail_expr| {
|
FlowHandler::MatchResult { .. } => map_tail_expr(block, |tail_expr| {
|
||||||
let ok = make::expr_path(make_path_from_text("Ok"));
|
let ok = make::expr_path(make::ext::ident_path("Ok"));
|
||||||
let args = make::arg_list(iter::once(tail_expr));
|
let args = make::arg_list(iter::once(tail_expr));
|
||||||
make::expr_call(ok, args)
|
make::expr_call(ok, args)
|
||||||
}),
|
}),
|
||||||
@ -1483,13 +1471,13 @@ fn make_rewritten_flow(handler: &FlowHandler, arg_expr: Option<ast::Expr>) -> Op
|
|||||||
FlowHandler::IfOption { .. } => {
|
FlowHandler::IfOption { .. } => {
|
||||||
let expr = arg_expr.unwrap_or_else(|| make::expr_tuple(Vec::new()));
|
let expr = arg_expr.unwrap_or_else(|| make::expr_tuple(Vec::new()));
|
||||||
let args = make::arg_list(iter::once(expr));
|
let args = make::arg_list(iter::once(expr));
|
||||||
make::expr_call(make::expr_path(make_path_from_text("Some")), args)
|
make::expr_call(make::expr_path(make::ext::ident_path("Some")), args)
|
||||||
}
|
}
|
||||||
FlowHandler::MatchOption { .. } => make::expr_path(make_path_from_text("None")),
|
FlowHandler::MatchOption { .. } => make::expr_path(make::ext::ident_path("None")),
|
||||||
FlowHandler::MatchResult { .. } => {
|
FlowHandler::MatchResult { .. } => {
|
||||||
let expr = arg_expr.unwrap_or_else(|| make::expr_tuple(Vec::new()));
|
let expr = arg_expr.unwrap_or_else(|| make::expr_tuple(Vec::new()));
|
||||||
let args = make::arg_list(iter::once(expr));
|
let args = make::arg_list(iter::once(expr));
|
||||||
make::expr_call(make::expr_path(make_path_from_text("Err")), args)
|
make::expr_call(make::expr_path(make::ext::ident_path("Err")), args)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Some(make::expr_return(Some(value)).clone_for_update())
|
Some(make::expr_return(Some(value)).clone_for_update())
|
||||||
|
@ -175,7 +175,7 @@ fn from_call(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render(self) -> FunctionTemplate {
|
fn render(self) -> FunctionTemplate {
|
||||||
let placeholder_expr = make::expr_todo();
|
let placeholder_expr = make::ext::expr_todo();
|
||||||
let fn_body = make::block_expr(vec![], Some(placeholder_expr));
|
let fn_body = make::block_expr(vec![], Some(placeholder_expr));
|
||||||
let visibility = if self.needs_pub { Some(make::visibility_pub_crate()) } else { None };
|
let visibility = if self.needs_pub { Some(make::visibility_pub_crate()) } else { None };
|
||||||
let mut fn_def = make::fn_(
|
let mut fn_def = make::fn_(
|
||||||
|
@ -63,11 +63,7 @@ pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build_predicate(param: ast::TypeParam) -> Option<ast::WherePred> {
|
fn build_predicate(param: ast::TypeParam) -> Option<ast::WherePred> {
|
||||||
let path = {
|
let path = make::ext::ident_path(¶m.name()?.syntax().to_string());
|
||||||
let name_ref = make::name_ref(¶m.name()?.syntax().to_string());
|
|
||||||
let segment = make::path_segment(name_ref);
|
|
||||||
make::path_unqualified(segment)
|
|
||||||
};
|
|
||||||
let predicate = make::where_pred(path, param.type_bound_list()?.bounds());
|
let predicate = make::where_pred(path, param.type_bound_list()?.bounds());
|
||||||
Some(predicate.clone_for_update())
|
Some(predicate.clone_for_update())
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ pub(crate) fn replace_derive_with_manual_impl(
|
|||||||
add_assist(acc, ctx, &attr, &args, &trait_path, Some(trait_), &adt)?;
|
add_assist(acc, ctx, &attr, &args, &trait_path, Some(trait_), &adt)?;
|
||||||
}
|
}
|
||||||
if no_traits_found {
|
if no_traits_found {
|
||||||
let trait_path = make::path_unqualified(make::path_segment(make::name_ref(trait_name)));
|
let trait_path = make::ext::ident_path(trait_name);
|
||||||
add_assist(acc, ctx, &attr, &args, &trait_path, None, &adt)?;
|
add_assist(acc, ctx, &attr, &args, &trait_path, None, &adt)?;
|
||||||
}
|
}
|
||||||
Some(())
|
Some(())
|
||||||
@ -159,10 +159,8 @@ fn impl_def_from_trait(
|
|||||||
if trait_items.is_empty() {
|
if trait_items.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let impl_def = make::impl_trait(
|
let impl_def =
|
||||||
trait_path.clone(),
|
make::impl_trait(trait_path.clone(), make::ext::ident_path(&annotated_name.text()));
|
||||||
make::path_unqualified(make::path_segment(make::name_ref(&annotated_name.text()))),
|
|
||||||
);
|
|
||||||
let (impl_def, first_assoc_item) =
|
let (impl_def, first_assoc_item) =
|
||||||
add_trait_assoc_items_to_impl(sema, trait_items, trait_, impl_def, target_scope);
|
add_trait_assoc_items_to_impl(sema, trait_items, trait_, impl_def, target_scope);
|
||||||
Some((impl_def, first_assoc_item))
|
Some((impl_def, first_assoc_item))
|
||||||
|
@ -53,7 +53,7 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext) ->
|
|||||||
let with_placeholder: ast::Pat = match happy_variant {
|
let with_placeholder: ast::Pat = match happy_variant {
|
||||||
None => make::wildcard_pat().into(),
|
None => make::wildcard_pat().into(),
|
||||||
Some(var_name) => make::tuple_struct_pat(
|
Some(var_name) => make::tuple_struct_pat(
|
||||||
make::path_unqualified(make::path_segment(make::name_ref(var_name))),
|
make::ext::ident_path(var_name),
|
||||||
once(make::wildcard_pat().into()),
|
once(make::wildcard_pat().into()),
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
// fn main() {
|
// fn main() {
|
||||||
// let x: Result<i32, i32> = Result::Ok(92);
|
// let x: Result<i32, i32> = Result::Ok(92);
|
||||||
// let y = match x {
|
// let y = match x {
|
||||||
// Ok(a) => a,
|
// Ok(it) => it,
|
||||||
// $0_ => unreachable!(),
|
// $0_ => unreachable!(),
|
||||||
// };
|
// };
|
||||||
// }
|
// }
|
||||||
@ -52,16 +52,17 @@ pub(crate) fn replace_unwrap_with_match(acc: &mut Assists, ctx: &AssistContext)
|
|||||||
"Replace unwrap with match",
|
"Replace unwrap with match",
|
||||||
target,
|
target,
|
||||||
|builder| {
|
|builder| {
|
||||||
let ok_path = make::path_unqualified(make::path_segment(make::name_ref(happy_variant)));
|
let ok_path = make::ext::ident_path(happy_variant);
|
||||||
let it = make::ident_pat(make::name("a")).into();
|
let it = make::ident_pat(make::name("it")).into();
|
||||||
let ok_tuple = make::tuple_struct_pat(ok_path, iter::once(it)).into();
|
let ok_tuple = make::tuple_struct_pat(ok_path, iter::once(it)).into();
|
||||||
|
|
||||||
let bind_path = make::path_unqualified(make::path_segment(make::name_ref("a")));
|
let bind_path = make::ext::ident_path("it");
|
||||||
let ok_arm = make::match_arm(iter::once(ok_tuple), make::expr_path(bind_path));
|
let ok_arm = make::match_arm(iter::once(ok_tuple), make::expr_path(bind_path));
|
||||||
|
|
||||||
let unreachable_call = make::expr_unreachable();
|
let err_arm = make::match_arm(
|
||||||
let err_arm =
|
iter::once(make::wildcard_pat().into()),
|
||||||
make::match_arm(iter::once(make::wildcard_pat().into()), unreachable_call);
|
make::ext::expr_unreachable(),
|
||||||
|
);
|
||||||
|
|
||||||
let match_arm_list = make::match_arm_list(vec![ok_arm, err_arm]);
|
let match_arm_list = make::match_arm_list(vec![ok_arm, err_arm]);
|
||||||
let match_expr = make::expr_match(caller.clone(), match_arm_list)
|
let match_expr = make::expr_match(caller.clone(), match_arm_list)
|
||||||
@ -110,7 +111,7 @@ fn i<T>(a: T) -> T { a }
|
|||||||
fn main() {
|
fn main() {
|
||||||
let x: Result<i32, i32> = Result::Ok(92);
|
let x: Result<i32, i32> = Result::Ok(92);
|
||||||
let y = match i(x) {
|
let y = match i(x) {
|
||||||
Ok(a) => a,
|
Ok(it) => it,
|
||||||
$0_ => unreachable!(),
|
$0_ => unreachable!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -136,7 +137,7 @@ fn i<T>(a: T) -> T { a }
|
|||||||
fn main() {
|
fn main() {
|
||||||
let x = Option::Some(92);
|
let x = Option::Some(92);
|
||||||
let y = match i(x) {
|
let y = match i(x) {
|
||||||
Some(a) => a,
|
Some(it) => it,
|
||||||
$0_ => unreachable!(),
|
$0_ => unreachable!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -162,7 +163,7 @@ fn i<T>(a: T) -> T { a }
|
|||||||
fn main() {
|
fn main() {
|
||||||
let x: Result<i32, i32> = Result::Ok(92);
|
let x: Result<i32, i32> = Result::Ok(92);
|
||||||
let y = match i(x) {
|
let y = match i(x) {
|
||||||
Ok(a) => a,
|
Ok(it) => it,
|
||||||
$0_ => unreachable!(),
|
$0_ => unreachable!(),
|
||||||
}.count_zeroes();
|
}.count_zeroes();
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,7 @@ pub(crate) fn wrap_return_type_in_result(acc: &mut Assists, ctx: &AssistContext)
|
|||||||
|
|
||||||
for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap {
|
for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap {
|
||||||
let ok_wrapped = make::expr_call(
|
let ok_wrapped = make::expr_call(
|
||||||
make::expr_path(make::path_unqualified(make::path_segment(make::name_ref(
|
make::expr_path(make::ext::ident_path("Ok")),
|
||||||
"Ok",
|
|
||||||
)))),
|
|
||||||
make::arg_list(iter::once(ret_expr_arg.clone())),
|
make::arg_list(iter::once(ret_expr_arg.clone())),
|
||||||
);
|
);
|
||||||
builder.replace_ast(ret_expr_arg, ok_wrapped);
|
builder.replace_ast(ret_expr_arg, ok_wrapped);
|
||||||
|
@ -1531,7 +1531,7 @@ enum Result<T, E> { Ok(T), Err(E) }
|
|||||||
fn main() {
|
fn main() {
|
||||||
let x: Result<i32, i32> = Result::Ok(92);
|
let x: Result<i32, i32> = Result::Ok(92);
|
||||||
let y = match x {
|
let y = match x {
|
||||||
Ok(a) => a,
|
Ok(it) => it,
|
||||||
$0_ => unreachable!(),
|
$0_ => unreachable!(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -159,8 +159,8 @@ fn add_body(fn_def: ast::Fn) -> ast::Fn {
|
|||||||
match fn_def.body() {
|
match fn_def.body() {
|
||||||
Some(_) => fn_def,
|
Some(_) => fn_def,
|
||||||
None => {
|
None => {
|
||||||
let body =
|
let body = make::block_expr(None, Some(make::ext::expr_todo()))
|
||||||
make::block_expr(None, Some(make::expr_todo())).indent(edit::IndentLevel(1));
|
.indent(edit::IndentLevel(1));
|
||||||
fn_def.with_body(body)
|
fn_def.with_body(body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ fn recursive_merge(
|
|||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
use_trees.insert(idx, make::glob_use_tree());
|
use_trees.insert(idx, make::use_tree_glob());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ pub fn happy_case(self) -> &'static str {
|
|||||||
pub fn sad_pattern(self) -> ast::Pat {
|
pub fn sad_pattern(self) -> ast::Pat {
|
||||||
match self {
|
match self {
|
||||||
TryEnum::Result => make::tuple_struct_pat(
|
TryEnum::Result => make::tuple_struct_pat(
|
||||||
make::path_unqualified(make::path_segment(make::name_ref("Err"))),
|
make::ext::ident_path("Err"),
|
||||||
iter::once(make::wildcard_pat().into()),
|
iter::once(make::wildcard_pat().into()),
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
@ -54,12 +54,12 @@ pub fn sad_pattern(self) -> ast::Pat {
|
|||||||
pub fn happy_pattern(self) -> ast::Pat {
|
pub fn happy_pattern(self) -> ast::Pat {
|
||||||
match self {
|
match self {
|
||||||
TryEnum::Result => make::tuple_struct_pat(
|
TryEnum::Result => make::tuple_struct_pat(
|
||||||
make::path_unqualified(make::path_segment(make::name_ref("Ok"))),
|
make::ext::ident_path("Ok"),
|
||||||
iter::once(make::wildcard_pat().into()),
|
iter::once(make::wildcard_pat().into()),
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
TryEnum::Option => make::tuple_struct_pat(
|
TryEnum::Option => make::tuple_struct_pat(
|
||||||
make::path_unqualified(make::path_segment(make::name_ref("Some"))),
|
make::ext::ident_path("Some"),
|
||||||
iter::once(make::wildcard_pat().into()),
|
iter::once(make::wildcard_pat().into()),
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Note that all functions here intended to be stupid constructors, which just
|
//! Note that all functions here intended to be stupid constructors, which just
|
||||||
//! assemble a finish node from immediate children. If you want to do something
|
//! assemble a finish node from immediate children. If you want to do something
|
||||||
//! smarter than that, it probably doesn't belong in this module.
|
//! smarter than that, it belongs to the `ext` submodule.
|
||||||
//!
|
//!
|
||||||
//! Keep in mind that `from_text` functions should be kept private. The public
|
//! Keep in mind that `from_text` functions should be kept private. The public
|
||||||
//! API should require to assemble every node piecewise. The trick of
|
//! API should require to assemble every node piecewise. The trick of
|
||||||
@ -14,13 +14,49 @@
|
|||||||
|
|
||||||
use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken};
|
use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken};
|
||||||
|
|
||||||
|
/// While the parent module defines basic atomic "constructors", the `ext`
|
||||||
|
/// module defines shortcuts for common things.
|
||||||
|
///
|
||||||
|
/// It's named `ext` rather than `shortcuts` just to keep it short.
|
||||||
|
pub mod ext {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn ident_path(ident: &str) -> ast::Path {
|
||||||
|
path_unqualified(path_segment(name_ref(ident)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expr_unreachable() -> ast::Expr {
|
||||||
|
expr_from_text("unreachable!()")
|
||||||
|
}
|
||||||
|
pub fn expr_todo() -> ast::Expr {
|
||||||
|
expr_from_text("todo!()")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ty_bool() -> ast::Type {
|
||||||
|
ty_path(ident_path("bool"))
|
||||||
|
}
|
||||||
|
pub fn ty_option(t: ast::Type) -> ast::Type {
|
||||||
|
ty_from_text(&format!("Option<{}>", t))
|
||||||
|
}
|
||||||
|
pub fn ty_result(t: ast::Type, e: ast::Type) -> ast::Type {
|
||||||
|
ty_from_text(&format!("Result<{}, {}>", t, e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn name(text: &str) -> ast::Name {
|
pub fn name(text: &str) -> ast::Name {
|
||||||
ast_from_text(&format!("mod {}{};", raw_ident_esc(text), text))
|
ast_from_text(&format!("mod {}{};", raw_ident_esc(text), text))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name_ref(text: &str) -> ast::NameRef {
|
pub fn name_ref(text: &str) -> ast::NameRef {
|
||||||
ast_from_text(&format!("fn f() {{ {}{}; }}", raw_ident_esc(text), text))
|
ast_from_text(&format!("fn f() {{ {}{}; }}", raw_ident_esc(text), text))
|
||||||
}
|
}
|
||||||
|
fn raw_ident_esc(ident: &str) -> &'static str {
|
||||||
|
let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some();
|
||||||
|
if is_keyword && !matches!(ident, "self" | "crate" | "super" | "Self") {
|
||||||
|
"r#"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn lifetime(text: &str) -> ast::Lifetime {
|
pub fn lifetime(text: &str) -> ast::Lifetime {
|
||||||
let mut text = text;
|
let mut text = text;
|
||||||
@ -32,15 +68,6 @@ pub fn lifetime(text: &str) -> ast::Lifetime {
|
|||||||
ast_from_text(&format!("fn f<{}>() {{ }}", text))
|
ast_from_text(&format!("fn f<{}>() {{ }}", text))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn raw_ident_esc(ident: &str) -> &'static str {
|
|
||||||
let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some();
|
|
||||||
if is_keyword && !matches!(ident, "self" | "crate" | "super" | "Self") {
|
|
||||||
"r#"
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: replace stringly-typed constructor with a family of typed ctors, a-la
|
// FIXME: replace stringly-typed constructor with a family of typed ctors, a-la
|
||||||
// `expr_xxx`.
|
// `expr_xxx`.
|
||||||
pub fn ty(text: &str) -> ast::Type {
|
pub fn ty(text: &str) -> ast::Type {
|
||||||
@ -49,9 +76,6 @@ pub fn ty(text: &str) -> ast::Type {
|
|||||||
pub fn ty_unit() -> ast::Type {
|
pub fn ty_unit() -> ast::Type {
|
||||||
ty_from_text("()")
|
ty_from_text("()")
|
||||||
}
|
}
|
||||||
pub fn ty_bool() -> ast::Type {
|
|
||||||
ty_path(path_unqualified(path_segment(name_ref("bool"))))
|
|
||||||
}
|
|
||||||
pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type {
|
pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type {
|
||||||
let mut count: usize = 0;
|
let mut count: usize = 0;
|
||||||
let mut contents = types.into_iter().inspect(|_| count += 1).join(", ");
|
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 {
|
|||||||
|
|
||||||
ty_from_text(&format!("({})", contents))
|
ty_from_text(&format!("({})", contents))
|
||||||
}
|
}
|
||||||
// FIXME: handle path to type
|
|
||||||
pub fn ty_generic(name: ast::NameRef, types: impl IntoIterator<Item = ast::Type>) -> ast::Type {
|
|
||||||
let contents = types.into_iter().join(", ");
|
|
||||||
ty_from_text(&format!("{}<{}>", name, contents))
|
|
||||||
}
|
|
||||||
pub fn ty_ref(target: ast::Type, exclusive: bool) -> ast::Type {
|
pub fn ty_ref(target: ast::Type, exclusive: bool) -> ast::Type {
|
||||||
ty_from_text(&if exclusive { format!("&mut {}", target) } else { format!("&{}", target) })
|
ty_from_text(&if exclusive { format!("&mut {}", target) } else { format!("&{}", target) })
|
||||||
}
|
}
|
||||||
@ -107,7 +126,7 @@ pub fn path_unqualified(segment: ast::PathSegment) -> ast::Path {
|
|||||||
pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path {
|
pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path {
|
||||||
ast_from_text(&format!("{}::{}", qual, segment))
|
ast_from_text(&format!("{}::{}", qual, segment))
|
||||||
}
|
}
|
||||||
|
// FIXME: path concatenation operation doesn't make sense as AST op.
|
||||||
pub fn path_concat(first: ast::Path, second: ast::Path) -> ast::Path {
|
pub fn path_concat(first: ast::Path, second: ast::Path) -> ast::Path {
|
||||||
ast_from_text(&format!("{}::{}", first, second))
|
ast_from_text(&format!("{}::{}", first, second))
|
||||||
}
|
}
|
||||||
@ -123,15 +142,14 @@ pub fn path_from_segments(
|
|||||||
format!("use {};", segments)
|
format!("use {};", segments)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// FIXME: should not be pub
|
||||||
pub fn path_from_text(text: &str) -> ast::Path {
|
pub fn path_from_text(text: &str) -> ast::Path {
|
||||||
ast_from_text(&format!("fn main() {{ let test = {}; }}", text))
|
ast_from_text(&format!("fn main() {{ let test = {}; }}", text))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn glob_use_tree() -> ast::UseTree {
|
pub fn use_tree_glob() -> ast::UseTree {
|
||||||
ast_from_text("use *;")
|
ast_from_text("use *;")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_tree(
|
pub fn use_tree(
|
||||||
path: ast::Path,
|
path: ast::Path,
|
||||||
use_tree_list: Option<ast::UseTreeList>,
|
use_tree_list: Option<ast::UseTreeList>,
|
||||||
@ -226,15 +244,6 @@ pub fn expr_literal(text: &str) -> ast::Literal {
|
|||||||
pub fn expr_empty_block() -> ast::Expr {
|
pub fn expr_empty_block() -> ast::Expr {
|
||||||
expr_from_text("{}")
|
expr_from_text("{}")
|
||||||
}
|
}
|
||||||
pub fn expr_unimplemented() -> ast::Expr {
|
|
||||||
expr_from_text("unimplemented!()")
|
|
||||||
}
|
|
||||||
pub fn expr_unreachable() -> ast::Expr {
|
|
||||||
expr_from_text("unreachable!()")
|
|
||||||
}
|
|
||||||
pub fn expr_todo() -> ast::Expr {
|
|
||||||
expr_from_text("todo!()")
|
|
||||||
}
|
|
||||||
pub fn expr_path(path: ast::Path) -> ast::Expr {
|
pub fn expr_path(path: ast::Path) -> ast::Expr {
|
||||||
expr_from_text(&path.to_string())
|
expr_from_text(&path.to_string())
|
||||||
}
|
}
|
||||||
@ -463,17 +472,6 @@ pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt {
|
|||||||
ast_from_text(&format!("fn f() {{ {}{} (); }}", expr, semi))
|
ast_from_text(&format!("fn f() {{ {}{} (); }}", expr, semi))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn token(kind: SyntaxKind) -> SyntaxToken {
|
|
||||||
tokens::SOURCE_FILE
|
|
||||||
.tree()
|
|
||||||
.syntax()
|
|
||||||
.clone_for_update()
|
|
||||||
.descendants_with_tokens()
|
|
||||||
.filter_map(|it| it.into_token())
|
|
||||||
.find(|it| it.kind() == kind)
|
|
||||||
.unwrap_or_else(|| panic!("unhandled token: {:?}", kind))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn param(pat: ast::Pat, ty: ast::Type) -> ast::Param {
|
pub fn param(pat: ast::Pat, ty: ast::Type) -> ast::Param {
|
||||||
ast_from_text(&format!("fn f({}: {}) {{ }}", pat, ty))
|
ast_from_text(&format!("fn f({}: {}) {{ }}", pat, ty))
|
||||||
}
|
}
|
||||||
@ -611,6 +609,17 @@ fn unroot(n: SyntaxNode) -> SyntaxNode {
|
|||||||
SyntaxNode::new_root(n.green().into())
|
SyntaxNode::new_root(n.green().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn token(kind: SyntaxKind) -> SyntaxToken {
|
||||||
|
tokens::SOURCE_FILE
|
||||||
|
.tree()
|
||||||
|
.syntax()
|
||||||
|
.clone_for_update()
|
||||||
|
.descendants_with_tokens()
|
||||||
|
.filter_map(|it| it.into_token())
|
||||||
|
.find(|it| it.kind() == kind)
|
||||||
|
.unwrap_or_else(|| panic!("unhandled token: {:?}", kind))
|
||||||
|
}
|
||||||
|
|
||||||
pub mod tokens {
|
pub mod tokens {
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user