From affd8d351863a4f9f5729eb3487942fa7bfa5755 Mon Sep 17 00:00:00 2001 From: unexge Date: Thu, 22 Apr 2021 11:33:56 +0300 Subject: Move reference editing logic into own function to make error handling more ease in "Convert to named struct" assist --- .../convert_tuple_struct_to_named_struct.rs | 129 ++++++++++----------- 1 file changed, 61 insertions(+), 68 deletions(-) (limited to 'crates/ide_assists') diff --git a/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs index 0df96be03..994e1a01a 100644 --- a/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/crates/ide_assists/src/handlers/convert_tuple_struct_to_named_struct.rs @@ -1,8 +1,7 @@ -use hir::{Adt, ModuleDef, Struct}; use ide_db::defs::{Definition, NameRefClass}; use syntax::{ ast::{self, AstNode, GenericParamsOwner, VisibilityOwner}, - match_ast, + match_ast, SyntaxNode, }; use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists}; @@ -104,80 +103,74 @@ fn edit_struct_def( fn edit_struct_references( ctx: &AssistContext, edit: &mut AssistBuilder, - strukt: Struct, + strukt: hir::Struct, names: &[ast::Name], ) { - let strukt_def = Definition::ModuleDef(ModuleDef::Adt(Adt::Struct(strukt))); + let strukt_def = Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Struct(strukt))); let usages = strukt_def.usages(&ctx.sema).include_self_kw_refs(true).all(); + let edit_node = |edit: &mut AssistBuilder, node: SyntaxNode| -> Option<()> { + match_ast! { + match node { + ast::TupleStructPat(tuple_struct_pat) => { + edit.replace( + tuple_struct_pat.syntax().text_range(), + ast::make::record_pat_with_fields( + tuple_struct_pat.path()?, + ast::make::record_pat_field_list(tuple_struct_pat.fields().zip(names).map( + |(pat, name)| { + ast::make::record_pat_field( + ast::make::name_ref(&name.to_string()), + pat, + ) + }, + )), + ) + .to_string(), + ); + }, + // for tuple struct creations like Foo(42) + ast::CallExpr(call_expr) => { + let path = call_expr.syntax().descendants().find_map(ast::PathExpr::cast).and_then(|expr| expr.path())?; + + // this also includes method calls like Foo::new(42), we should skip them + if let Some(name_ref) = path.segment().and_then(|s| s.name_ref()) { + match NameRefClass::classify(&ctx.sema, &name_ref) { + Some(NameRefClass::Definition(Definition::SelfType(_))) => {}, + Some(NameRefClass::Definition(def)) if def == strukt_def => {}, + _ => return None, + }; + } + + let arg_list = call_expr.syntax().descendants().find_map(ast::ArgList::cast)?; + + edit.replace( + call_expr.syntax().text_range(), + ast::make::record_expr( + path, + ast::make::record_expr_field_list(arg_list.args().zip(names).map( + |(expr, name)| { + ast::make::record_expr_field( + ast::make::name_ref(&name.to_string()), + Some(expr), + ) + }, + )), + ) + .to_string(), + ); + }, + _ => () + } + } + Some(()) + }; + for (file_id, refs) in usages { edit.edit_file(file_id); for r in refs { for node in r.name.syntax().ancestors() { - match_ast! { - match node { - ast::TupleStructPat(tuple_struct_pat) => { - let path = match tuple_struct_pat.path() { - Some(it) => it, - None => continue, - }; - - edit.replace( - tuple_struct_pat.syntax().text_range(), - ast::make::record_pat_with_fields( - path, - ast::make::record_pat_field_list(tuple_struct_pat.fields().zip(names).map( - |(pat, name)| { - ast::make::record_pat_field( - ast::make::name_ref(&name.to_string()), - pat, - ) - }, - )), - ) - .to_string(), - ); - }, - // for tuple struct creations like Foo(42) - ast::CallExpr(call_expr) => { - let path = match call_expr.syntax().descendants().find_map(ast::PathExpr::cast).map(|expr| expr.path()) { - Some(Some(it)) => it, - _ => continue, - }; - - // this also includes method calls like Foo::new(42), we should skip them - if let Some(Some(name_ref)) = path.segment().map(|s| s.name_ref()) { - match NameRefClass::classify(&ctx.sema, &name_ref) { - Some(NameRefClass::Definition(Definition::SelfType(_))) => {}, - Some(NameRefClass::Definition(def)) if def == strukt_def => {}, - _ => continue, - }; - } - - let arg_list = match call_expr.syntax().descendants().find_map(ast::ArgList::cast) { - Some(it) => it, - None => continue, - }; - - edit.replace( - call_expr.syntax().text_range(), - ast::make::record_expr( - path, - ast::make::record_expr_field_list(arg_list.args().zip(names).map( - |(expr, name)| { - ast::make::record_expr_field( - ast::make::name_ref(&name.to_string()), - Some(expr), - ) - }, - )), - ) - .to_string(), - ); - }, - _ => () - } - } + edit_node(edit, node); } } } -- cgit v1.2.3