Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/utils.rs')
-rw-r--r--crates/ide-assists/src/utils.rs124
1 files changed, 4 insertions, 120 deletions
diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs
index 0227222c08..db32e7182c 100644
--- a/crates/ide-assists/src/utils.rs
+++ b/crates/ide-assists/src/utils.rs
@@ -4,27 +4,21 @@ use std::ops;
pub(crate) use gen_trait_fn_body::gen_trait_fn_body;
use hir::{db::HirDatabase, HirDisplay, Semantics};
-use ide_db::{
- assists::{AssistId, AssistKind},
- famous_defs::FamousDefs,
- path_transform::PathTransform,
- RootDatabase, SnippetCap,
-};
+use ide_db::{famous_defs::FamousDefs, path_transform::PathTransform, RootDatabase, SnippetCap};
use stdx::format_to;
use syntax::{
ast::{
self,
edit::{self, AstNodeEdit},
edit_in_place::{AttrsOwnerEdit, Removable},
- make, ArithOp, BinExpr, BinaryOp, Expr, HasArgList, HasAttrs, HasGenericParams, HasName,
- HasTypeBounds, Whitespace,
+ make, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace,
},
- ted, AstNode, AstToken, Direction, SmolStr, SourceFile,
+ ted, AstNode, AstToken, Direction, SourceFile,
SyntaxKind::*,
SyntaxNode, TextRange, TextSize, T,
};
-use crate::assist_context::{AssistContext, Assists, SourceChangeBuilder};
+use crate::assist_context::{AssistContext, SourceChangeBuilder};
pub(crate) mod suggest_name;
mod gen_trait_fn_body;
@@ -711,113 +705,3 @@ pub(crate) fn convert_param_list_to_arg_list(list: ast::ParamList) -> ast::ArgLi
}
make::arg_list(args)
}
-
-pub(crate) enum ArithKind {
- Saturating,
- Wrapping,
- Checked,
-}
-
-impl ArithKind {
- fn assist_id(&self) -> AssistId {
- let s = match self {
- ArithKind::Saturating => "replace_arith_with_saturating",
- ArithKind::Checked => "replace_arith_with_checked",
- ArithKind::Wrapping => "replace_arith_with_wrapping",
- };
-
- AssistId(s, AssistKind::RefactorRewrite)
- }
-
- fn label(&self) -> &'static str {
- match self {
- ArithKind::Saturating => "Replace arithmetic with call to saturating_*",
- ArithKind::Checked => "Replace arithmetic with call to checked_*",
- ArithKind::Wrapping => "Replace arithmetic with call to wrapping_*",
- }
- }
-
- fn method_name(&self, op: ArithOp) -> SmolStr {
- // is this too much effort to avoid an allocation? is there a better way?
- let mut bytes = [0u8; 14];
- let prefix = match self {
- ArithKind::Checked => "checked_",
- ArithKind::Wrapping => "wrapping_",
- ArithKind::Saturating => "saturating_",
- };
-
- bytes[0..(prefix.len())].copy_from_slice(prefix.as_bytes());
-
- let suffix = match op {
- ArithOp::Add => "add",
- ArithOp::Sub => "sub",
- ArithOp::Mul => "mul",
- ArithOp::Div => "div",
- _ => unreachable!("this function should only be called with +, -, / or *"),
- };
-
- bytes[(prefix.len())..(prefix.len() + suffix.len())].copy_from_slice(suffix.as_bytes());
-
- let len = prefix.len() + suffix.len();
- let s = core::str::from_utf8(&bytes[0..len]).unwrap();
- SmolStr::from(s)
- }
-}
-
-pub(crate) fn replace_arith(
- acc: &mut Assists,
- ctx: &AssistContext<'_>,
- kind: ArithKind,
-) -> Option<()> {
- let (lhs, op, rhs) = parse_binary_op(ctx)?;
-
- if !is_primitive_int(ctx, &lhs) || !is_primitive_int(ctx, &rhs) {
- return None;
- }
-
- let start = lhs.syntax().text_range().start();
- let end = rhs.syntax().text_range().end();
- let range = TextRange::new(start, end);
-
- acc.add(kind.assist_id(), kind.label(), range, |builder| {
- let method_name = kind.method_name(op);
-
- builder.replace(range, format!("{lhs}.{method_name}({rhs})"))
- })
-}
-
-fn is_primitive_int(ctx: &AssistContext<'_>, expr: &Expr) -> bool {
- match ctx.sema.type_of_expr(expr) {
- Some(ty) => ty.adjusted().is_int_or_uint(),
- _ => false,
- }
-}
-
-/// Extract the operands of an arithmetic expression (e.g. `1 + 2` or `1.checked_add(2)`)
-fn parse_binary_op(ctx: &AssistContext<'_>) -> Option<(Expr, ArithOp, Expr)> {
- let expr = ctx.find_node_at_offset::<BinExpr>()?;
-
- let op = match expr.op_kind() {
- Some(BinaryOp::ArithOp(ArithOp::Add)) => ArithOp::Add,
- Some(BinaryOp::ArithOp(ArithOp::Sub)) => ArithOp::Sub,
- Some(BinaryOp::ArithOp(ArithOp::Mul)) => ArithOp::Mul,
- Some(BinaryOp::ArithOp(ArithOp::Div)) => ArithOp::Div,
- _ => return None,
- };
-
- let lhs = expr.lhs()?;
- let rhs = expr.rhs()?;
-
- Some((lhs, op, rhs))
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn arith_kind_method_name() {
- assert_eq!(ArithKind::Saturating.method_name(ArithOp::Add), "saturating_add");
- assert_eq!(ArithKind::Checked.method_name(ArithOp::Sub), "checked_sub");
- }
-}