Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 25088fc

Browse files
committed
Migrate generate_derive to mutable ast
1 parent 419f641 commit 25088fc

File tree

1 file changed

+31
-43
lines changed

1 file changed

+31
-43
lines changed

crates/ide-assists/src/handlers/generate_derive.rs

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use syntax::{
2-
ast::{self, edit::IndentLevel, AstNode, HasAttrs},
3-
SyntaxKind::{COMMENT, WHITESPACE},
4-
TextSize,
2+
ast::{self, edit_in_place::AttrsOwnerEdit, make, AstNode, HasAttrs},
3+
T,
54
};
65

76
use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -27,48 +26,37 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
2726
pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
2827
let cap = ctx.config.snippet_cap?;
2928
let nominal = ctx.find_node_at_offset::<ast::Adt>()?;
30-
let node_start = derive_insertion_offset(&nominal)?;
3129
let target = nominal.syntax().text_range();
32-
acc.add(
33-
AssistId("generate_derive", AssistKind::Generate),
34-
"Add `#[derive]`",
35-
target,
36-
|builder| {
37-
let derive_attr = nominal
38-
.attrs()
39-
.filter_map(|x| x.as_simple_call())
40-
.filter(|(name, _arg)| name == "derive")
41-
.map(|(_name, arg)| arg)
42-
.next();
43-
match derive_attr {
44-
None => {
45-
let indent_level = IndentLevel::from_node(nominal.syntax());
46-
builder.insert_snippet(
47-
cap,
48-
node_start,
49-
format!("#[derive($0)]\n{indent_level}"),
50-
);
51-
}
52-
Some(tt) => {
53-
// Just move the cursor.
54-
builder.insert_snippet(
55-
cap,
56-
tt.syntax().text_range().end() - TextSize::of(')'),
57-
"$0",
58-
)
59-
}
60-
};
61-
},
62-
)
63-
}
30+
acc.add(AssistId("generate_derive", AssistKind::Generate), "Add `#[derive]`", target, |edit| {
31+
let derive_attr = nominal
32+
.attrs()
33+
.filter_map(|x| x.as_simple_call())
34+
.filter(|(name, _arg)| name == "derive")
35+
.map(|(_name, arg)| arg)
36+
.next();
37+
match derive_attr {
38+
None => {
39+
let derive = make::attr_outer(make::meta_token_tree(
40+
make::ext::ident_path("derive"),
41+
make::token_tree(T!['('], vec![]).clone_for_update(),
42+
))
43+
.clone_for_update();
44+
45+
let nominal = edit.make_mut(nominal);
46+
nominal.add_attr(derive.clone());
6447

65-
// Insert `derive` after doc comments.
66-
fn derive_insertion_offset(nominal: &ast::Adt) -> Option<TextSize> {
67-
let non_ws_child = nominal
68-
.syntax()
69-
.children_with_tokens()
70-
.find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?;
71-
Some(non_ws_child.text_range().start())
48+
edit.add_tabstop_before_token(
49+
cap,
50+
derive.meta().unwrap().token_tree().unwrap().r_paren_token().unwrap(),
51+
);
52+
}
53+
Some(tt) => {
54+
// Just move the cursor.
55+
let tt = edit.make_mut(tt);
56+
edit.add_tabstop_before_token(cap, tt.r_paren_token().unwrap());
57+
}
58+
};
59+
})
7260
}
7361

7462
#[cfg(test)]

0 commit comments

Comments
 (0)