Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/utils/gen_trait_fn_body.rs')
| -rw-r--r-- | crates/ide-assists/src/utils/gen_trait_fn_body.rs | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/crates/ide-assists/src/utils/gen_trait_fn_body.rs b/crates/ide-assists/src/utils/gen_trait_fn_body.rs index c58bdd9e8e..87e90e8519 100644 --- a/crates/ide-assists/src/utils/gen_trait_fn_body.rs +++ b/crates/ide-assists/src/utils/gen_trait_fn_body.rs @@ -1,10 +1,7 @@ //! This module contains functions to generate default trait impl function bodies where possible. use hir::TraitRef; -use syntax::{ - ast::{self, AstNode, BinaryOp, CmpOp, HasName, LogicOp, edit::AstNodeEdit, make}, - ted, -}; +use syntax::ast::{self, AstNode, BinaryOp, CmpOp, HasName, LogicOp, edit::AstNodeEdit, make}; /// Generate custom trait bodies without default implementation where possible. /// @@ -18,21 +15,33 @@ pub(crate) fn gen_trait_fn_body( trait_path: &ast::Path, adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>, -) -> Option<()> { +) -> Option<ast::BlockExpr> { + let _ = func.body()?; match trait_path.segment()?.name_ref()?.text().as_str() { - "Clone" => gen_clone_impl(adt, func), - "Debug" => gen_debug_impl(adt, func), - "Default" => gen_default_impl(adt, func), - "Hash" => gen_hash_impl(adt, func), - "PartialEq" => gen_partial_eq(adt, func, trait_ref), - "PartialOrd" => gen_partial_ord(adt, func, trait_ref), + "Clone" => { + stdx::always!(func.name().is_some_and(|name| name.text() == "clone")); + gen_clone_impl(adt) + } + "Debug" => gen_debug_impl(adt), + "Default" => gen_default_impl(adt), + "Hash" => { + stdx::always!(func.name().is_some_and(|name| name.text() == "hash")); + gen_hash_impl(adt) + } + "PartialEq" => { + stdx::always!(func.name().is_some_and(|name| name.text() == "eq")); + gen_partial_eq(adt, trait_ref) + } + "PartialOrd" => { + stdx::always!(func.name().is_some_and(|name| name.text() == "partial_cmp")); + gen_partial_ord(adt, trait_ref) + } _ => None, } } /// Generate a `Clone` impl based on the fields and members of the target type. -fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> { - stdx::always!(func.name().is_some_and(|name| name.text() == "clone")); +fn gen_clone_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> { fn gen_clone_call(target: ast::Expr) -> ast::Expr { let method = make::name_ref("clone"); make::expr_method_call(target, method, make::arg_list(None)).into() @@ -139,12 +148,11 @@ fn gen_clone_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> { } }; let body = make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1)); - ted::replace(func.body()?.syntax(), body.clone_for_update().syntax()); - Some(()) + Some(body) } /// Generate a `Debug` impl based on the fields and members of the target type. -fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> { +fn gen_debug_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> { let annotated_name = adt.name()?; match adt { // `Debug` cannot be derived for unions, so no default impl can be provided. @@ -248,8 +256,7 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> { let body = make::block_expr(None, Some(match_expr.into())); let body = body.indent(ast::edit::IndentLevel(1)); - ted::replace(func.body()?.syntax(), body.clone_for_update().syntax()); - Some(()) + Some(body) } ast::Adt::Struct(strukt) => { @@ -296,14 +303,13 @@ fn gen_debug_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> { let method = make::name_ref("finish"); let expr = make::expr_method_call(expr, method, make::arg_list(None)).into(); let body = make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1)); - ted::replace(func.body()?.syntax(), body.clone_for_update().syntax()); - Some(()) + Some(body) } } } /// Generate a `Debug` impl based on the fields and members of the target type. -fn gen_default_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> { +fn gen_default_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> { fn gen_default_call() -> Option<ast::Expr> { let fn_name = make::ext::path_from_idents(["Default", "default"])?; Some(make::expr_call(make::expr_path(fn_name), make::arg_list(None)).into()) @@ -342,15 +348,13 @@ fn gen_default_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> { } }; let body = make::block_expr(None, Some(expr)).indent(ast::edit::IndentLevel(1)); - ted::replace(func.body()?.syntax(), body.clone_for_update().syntax()); - Some(()) + Some(body) } } } /// Generate a `Hash` impl based on the fields and members of the target type. -fn gen_hash_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> { - stdx::always!(func.name().is_some_and(|name| name.text() == "hash")); +fn gen_hash_impl(adt: &ast::Adt) -> Option<ast::BlockExpr> { fn gen_hash_call(target: ast::Expr) -> ast::Stmt { let method = make::name_ref("hash"); let arg = make::expr_path(make::ext::ident_path("state")); @@ -400,13 +404,11 @@ fn gen_hash_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> { }, }; - ted::replace(func.body()?.syntax(), body.clone_for_update().syntax()); - Some(()) + Some(body) } /// Generate a `PartialEq` impl based on the fields and members of the target type. -fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option<TraitRef<'_>>) -> Option<()> { - stdx::always!(func.name().is_some_and(|name| name.text() == "eq")); +fn gen_partial_eq(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<ast::BlockExpr> { fn gen_eq_chain(expr: Option<ast::Expr>, cmp: ast::Expr) -> Option<ast::Expr> { match expr { Some(expr) => Some(make::expr_bin_op(expr, BinaryOp::LogicOp(LogicOp::And), cmp)), @@ -595,12 +597,10 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option<TraitRef<'_> }, }; - ted::replace(func.body()?.syntax(), body.clone_for_update().syntax()); - Some(()) + Some(body) } -fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option<TraitRef<'_>>) -> Option<()> { - stdx::always!(func.name().is_some_and(|name| name.text() == "partial_cmp")); +fn gen_partial_ord(adt: &ast::Adt, trait_ref: Option<TraitRef<'_>>) -> Option<ast::BlockExpr> { fn gen_partial_eq_match(match_target: ast::Expr) -> Option<ast::Stmt> { let mut arms = vec![]; @@ -686,8 +686,7 @@ fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option<TraitRef<'_ }, }; - ted::replace(func.body()?.syntax(), body.clone_for_update().syntax()); - Some(()) + Some(body) } fn make_discriminant() -> Option<ast::Expr> { |