From afc68277f69572944fd81d61b126732ab29b5d17 Mon Sep 17 00:00:00 2001 From: Vladyslav Katasonov Date: Tue, 16 Feb 2021 23:48:15 +0300 Subject: pull out suggest_name::* to utils; enchance heuristics --- .../ide_assists/src/handlers/extract_variable.rs | 92 +--------------------- 1 file changed, 4 insertions(+), 88 deletions(-) (limited to 'crates/ide_assists/src/handlers') diff --git a/crates/ide_assists/src/handlers/extract_variable.rs b/crates/ide_assists/src/handlers/extract_variable.rs index 2c47be987..312ac7ac4 100644 --- a/crates/ide_assists/src/handlers/extract_variable.rs +++ b/crates/ide_assists/src/handlers/extract_variable.rs @@ -1,7 +1,6 @@ -use itertools::Itertools; -use stdx::{format_to, to_lower_snake_case}; +use stdx::format_to; use syntax::{ - ast::{self, AstNode, NameOwner}, + ast::{self, AstNode}, SyntaxKind::{ BLOCK_EXPR, BREAK_EXPR, CLOSURE_EXPR, COMMENT, LOOP_EXPR, MATCH_ARM, PATH_EXPR, RETURN_EXPR, }, @@ -9,7 +8,7 @@ use syntax::{ }; use test_utils::mark; -use crate::{AssistContext, AssistId, AssistKind, Assists}; +use crate::{utils::suggest_name, AssistContext, AssistId, AssistKind, Assists}; // Assist: extract_variable // @@ -55,7 +54,7 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option let var_name = match &field_shorthand { Some(it) => it.to_string(), - None => suggest_variable_name(ctx, &to_extract), + None => suggest_name::variable(&to_extract, &ctx.sema), }; let expr_range = match &field_shorthand { Some(it) => it.syntax().text_range().cover(to_extract.syntax().text_range()), @@ -174,89 +173,6 @@ impl Anchor { } } -fn suggest_variable_name(ctx: &AssistContext, expr: &ast::Expr) -> String { - // FIXME: account for existing names in the scope - suggest_name_from_param(ctx, expr) - .or_else(|| suggest_name_from_func(expr)) - .or_else(|| suggest_name_from_method(expr)) - .or_else(|| suggest_name_by_type(ctx, expr)) - .unwrap_or_else(|| "var_name".to_string()) -} - -fn normalize_name(name: &str) -> Option { - let name = to_lower_snake_case(name); - - let useless_names = ["new", "default", "some", "none", "ok", "err"]; - if useless_names.contains(&name.as_str()) { - return None; - } - - Some(name) -} - -fn suggest_name_from_func(expr: &ast::Expr) -> Option { - let call = match expr { - ast::Expr::CallExpr(call) => call, - _ => return None, - }; - let func = match call.expr()? { - ast::Expr::PathExpr(path) => path, - _ => return None, - }; - let ident = func.path()?.segment()?.name_ref()?.ident_token()?; - normalize_name(ident.text()) -} - -fn suggest_name_from_method(expr: &ast::Expr) -> Option { - let method = match expr { - ast::Expr::MethodCallExpr(call) => call, - _ => return None, - }; - let ident = method.name_ref()?.ident_token()?; - normalize_name(ident.text()) -} - -fn suggest_name_from_param(ctx: &AssistContext, expr: &ast::Expr) -> Option { - let arg_list = expr.syntax().parent().and_then(ast::ArgList::cast)?; - let args_parent = arg_list.syntax().parent()?; - let func = if let Some(call) = ast::CallExpr::cast(args_parent.clone()) { - let func = call.expr()?; - let func_ty = ctx.sema.type_of_expr(&func)?; - func_ty.as_callable(ctx.db())? - } else if let Some(method) = ast::MethodCallExpr::cast(args_parent) { - ctx.sema.resolve_method_call_as_callable(&method)? - } else { - return None; - }; - - let (idx, _) = arg_list.args().find_position(|it| it == expr).unwrap(); - let (pat, _) = func.params(ctx.db()).into_iter().nth(idx)?; - let param = match pat? { - either::Either::Right(ast::Pat::IdentPat(param)) => param, - _ => return None, - }; - let name = param.name()?; - normalize_name(&name.to_string()) -} - -fn suggest_name_by_type(ctx: &AssistContext, expr: &ast::Expr) -> Option { - let ty = ctx.sema.type_of_expr(expr)?; - let ty = ty.remove_ref().unwrap_or(ty); - - name_from_type(ty, ctx) -} - -fn name_from_type(ty: hir::Type, ctx: &AssistContext) -> Option { - let name = if let Some(adt) = ty.as_adt() { - adt.name(ctx.db()).to_string() - } else if let Some(trait_) = ty.as_dyn_trait() { - trait_.name(ctx.db()).to_string() - } else { - return None; - }; - normalize_name(&name) -} - #[cfg(test)] mod tests { use test_utils::mark; -- cgit v1.2.3