From 94b3481808e5033cf45800cc9e22e15d5245aa1a Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 10 Aug 2023 01:46:51 +0200 Subject: [PATCH 1/2] Deunwrap generate_derive --- .../src/handlers/generate_derive.rs | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/crates/ide-assists/src/handlers/generate_derive.rs b/crates/ide-assists/src/handlers/generate_derive.rs index 747f70f9f6..5e67537c80 100644 --- a/crates/ide-assists/src/handlers/generate_derive.rs +++ b/crates/ide-assists/src/handlers/generate_derive.rs @@ -27,33 +27,45 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt let cap = ctx.config.snippet_cap?; let nominal = ctx.find_node_at_offset::()?; let target = nominal.syntax().text_range(); + let derive_attr = nominal + .attrs() + .filter_map(|x| x.as_simple_call()) + .filter(|(name, _arg)| name == "derive") + .map(|(_name, arg)| arg) + .next(); + + let (derive, delimiter) = match &derive_attr { + None => { + let derive = make::attr_outer(make::meta_token_tree( + make::ext::ident_path("derive"), + make::token_tree(T!['('], vec![]).clone_for_update(), + )) + .clone_for_update(); + let delimiter = derive.meta()?.token_tree()?.r_paren_token()?; + (derive, delimiter) + } + Some(tt) => { + // Create an outer attribute just so that we avoid using + // unwrap in edit closure. + let _derive = make::attr_outer(make::meta_token_tree( + make::ext::ident_path("derive"), + make::token_tree(T!['('], vec![]), + )); + (_derive, tt.right_delimiter_token()?) + } + }; + acc.add(AssistId("generate_derive", AssistKind::Generate), "Add `#[derive]`", target, |edit| { - let derive_attr = nominal - .attrs() - .filter_map(|x| x.as_simple_call()) - .filter(|(name, _arg)| name == "derive") - .map(|(_name, arg)| arg) - .next(); match derive_attr { None => { - let derive = make::attr_outer(make::meta_token_tree( - make::ext::ident_path("derive"), - make::token_tree(T!['('], vec![]).clone_for_update(), - )) - .clone_for_update(); - let nominal = edit.make_mut(nominal); nominal.add_attr(derive.clone()); - edit.add_tabstop_before_token( - cap, - derive.meta().unwrap().token_tree().unwrap().r_paren_token().unwrap(), - ); + edit.add_tabstop_before_token(cap, delimiter); } - Some(tt) => { + Some(_) => { // Just move the cursor. - let tt = edit.make_mut(tt); - edit.add_tabstop_before_token(cap, tt.right_delimiter_token().unwrap()); + edit.add_tabstop_before_token(cap, delimiter); } }; }) From 2a78173ff86753bfe9525943925a98d2636c6da1 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Wed, 16 Aug 2023 00:22:08 +0200 Subject: [PATCH 2/2] v2 --- .../src/handlers/generate_derive.rs | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/crates/ide-assists/src/handlers/generate_derive.rs b/crates/ide-assists/src/handlers/generate_derive.rs index 5e67537c80..53ba144ba9 100644 --- a/crates/ide-assists/src/handlers/generate_derive.rs +++ b/crates/ide-assists/src/handlers/generate_derive.rs @@ -34,38 +34,39 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt .map(|(_name, arg)| arg) .next(); - let (derive, delimiter) = match &derive_attr { - None => { - let derive = make::attr_outer(make::meta_token_tree( - make::ext::ident_path("derive"), - make::token_tree(T!['('], vec![]).clone_for_update(), - )) - .clone_for_update(); - let delimiter = derive.meta()?.token_tree()?.r_paren_token()?; - (derive, delimiter) - } - Some(tt) => { - // Create an outer attribute just so that we avoid using - // unwrap in edit closure. - let _derive = make::attr_outer(make::meta_token_tree( - make::ext::ident_path("derive"), - make::token_tree(T!['('], vec![]), - )); - (_derive, tt.right_delimiter_token()?) - } + let delimiter = match &derive_attr { + None => None, + Some(tt) => Some(tt.right_delimiter_token()?), }; acc.add(AssistId("generate_derive", AssistKind::Generate), "Add `#[derive]`", target, |edit| { match derive_attr { None => { + let derive = make::attr_outer(make::meta_token_tree( + make::ext::ident_path("derive"), + make::token_tree(T!['('], vec![]).clone_for_update(), + )) + .clone_for_update(); + let nominal = edit.make_mut(nominal); nominal.add_attr(derive.clone()); + let delimiter = derive + .meta() + .expect("make::attr_outer was expected to have Meta") + .token_tree() + .expect("failed to get token tree out of Meta") + .r_paren_token() + .expect("make::attr_outer was expected to have a R_PAREN"); + edit.add_tabstop_before_token(cap, delimiter); } Some(_) => { // Just move the cursor. - edit.add_tabstop_before_token(cap, delimiter); + edit.add_tabstop_before_token( + cap, + delimiter.expect("Right delim token could not be found."), + ); } }; })