Skip to content

Commit e011715

Browse files
committed
Migrate generate_impl to mutable ast
1 parent ab2233e commit e011715

File tree

2 files changed

+53
-81
lines changed

2 files changed

+53
-81
lines changed

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

Lines changed: 51 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use syntax::ast::{self, AstNode, HasName};
2-
3-
use crate::{
4-
utils::{generate_impl_text, generate_trait_impl_text_intransitive},
5-
AssistContext, AssistId, AssistKind, Assists,
1+
use syntax::{
2+
ast::{self, make, AstNode, HasName},
3+
ted,
64
};
75

6+
use crate::{utils, AssistContext, AssistId, AssistKind, Assists};
7+
88
// Assist: generate_impl
99
//
1010
// Adds a new inherent impl for a type.
@@ -20,9 +20,7 @@ use crate::{
2020
// data: T,
2121
// }
2222
//
23-
// impl<T: Clone> Ctx<T> {
24-
// $0
25-
// }
23+
// impl<T: Clone> Ctx<T> {$0}
2624
// ```
2725
pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
2826
let nominal = ctx.find_node_at_offset::<ast::Adt>()?;
@@ -38,17 +36,22 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
3836
format!("Generate impl for `{name}`"),
3937
target,
4038
|edit| {
41-
let start_offset = nominal.syntax().text_range().end();
42-
match ctx.config.snippet_cap {
43-
Some(cap) => {
44-
let snippet = generate_impl_text(&nominal, " $0");
45-
edit.insert_snippet(cap, start_offset, snippet);
46-
}
47-
None => {
48-
let snippet = generate_impl_text(&nominal, "");
49-
edit.insert(start_offset, snippet);
39+
// Generate the impl
40+
let impl_ = utils::generate_impl(&nominal);
41+
42+
// Add a tabstop after the left curly brace
43+
if let Some(cap) = ctx.config.snippet_cap {
44+
if let Some(l_curly) = impl_.assoc_item_list().and_then(|it| it.l_curly_token()) {
45+
edit.add_tabstop_after_token(cap, l_curly);
5046
}
5147
}
48+
49+
// Add the impl after the adt
50+
let nominal = edit.make_mut(nominal);
51+
ted::insert_all_raw(
52+
ted::Position::after(nominal.syntax()),
53+
vec![make::tokens::blank_line().into(), impl_.syntax().clone().into()],
54+
);
5255
},
5356
)
5457
}
@@ -68,9 +71,7 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
6871
// data: T,
6972
// }
7073
//
71-
// impl<T: Clone> $0 for Ctx<T> {
72-
//
73-
// }
74+
// impl<T: Clone> ${0:_} for Ctx<T> {}
7475
// ```
7576
pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
7677
let nominal = ctx.find_node_at_offset::<ast::Adt>()?;
@@ -86,17 +87,22 @@ pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) ->
8687
format!("Generate trait impl for `{name}`"),
8788
target,
8889
|edit| {
89-
let start_offset = nominal.syntax().text_range().end();
90-
match ctx.config.snippet_cap {
91-
Some(cap) => {
92-
let snippet = generate_trait_impl_text_intransitive(&nominal, "$0", "");
93-
edit.insert_snippet(cap, start_offset, snippet);
94-
}
95-
None => {
96-
let text = generate_trait_impl_text_intransitive(&nominal, "", "");
97-
edit.insert(start_offset, text);
90+
// Generate the impl
91+
let impl_ = utils::generate_trait_impl_intransitive(&nominal, make::ty_placeholder());
92+
93+
// Make the trait type a placeholder snippet
94+
if let Some(cap) = ctx.config.snippet_cap {
95+
if let Some(trait_) = impl_.trait_() {
96+
edit.add_placeholder_snippet(cap, trait_);
9897
}
9998
}
99+
100+
// Add the impl after the adt
101+
let nominal = edit.make_mut(nominal);
102+
ted::insert_all_raw(
103+
ted::Position::after(nominal.syntax()),
104+
vec![make::tokens::blank_line().into(), impl_.syntax().clone().into()],
105+
);
100106
},
101107
)
102108
}
@@ -117,9 +123,7 @@ mod tests {
117123
r#"
118124
struct Foo {}
119125
120-
impl Foo {
121-
$0
122-
}
126+
impl Foo {$0}
123127
"#,
124128
);
125129
}
@@ -134,9 +138,7 @@ mod tests {
134138
r#"
135139
struct Foo<T: Clone> {}
136140
137-
impl<T: Clone> Foo<T> {
138-
$0
139-
}
141+
impl<T: Clone> Foo<T> {$0}
140142
"#,
141143
);
142144
}
@@ -151,9 +153,7 @@ mod tests {
151153
r#"
152154
struct Foo<'a, T: Foo<'a>> {}
153155
154-
impl<'a, T: Foo<'a>> Foo<'a, T> {
155-
$0
156-
}
156+
impl<'a, T: Foo<'a>> Foo<'a, T> {$0}
157157
"#,
158158
);
159159
}
@@ -171,9 +171,7 @@ mod tests {
171171
struct Foo<'a, T: Foo<'a>> {}
172172
173173
#[cfg(feature = "foo")]
174-
impl<'a, T: Foo<'a>> Foo<'a, T> {
175-
$0
176-
}
174+
impl<'a, T: Foo<'a>> Foo<'a, T> {$0}
177175
"#,
178176
);
179177
}
@@ -188,9 +186,7 @@ mod tests {
188186
r#"
189187
struct Defaulted<T = i32> {}
190188
191-
impl<T> Defaulted<T> {
192-
$0
193-
}
189+
impl<T> Defaulted<T> {$0}
194190
"#,
195191
);
196192
}
@@ -205,9 +201,7 @@ mod tests {
205201
r#"
206202
struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {}
207203
208-
impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> Defaulted<'a, 'b, T, S> {
209-
$0
210-
}
204+
impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> Defaulted<'a, 'b, T, S> {$0}
211205
"#,
212206
);
213207
}
@@ -222,9 +216,7 @@ mod tests {
222216
r#"
223217
struct Defaulted<const N: i32 = 0> {}
224218
225-
impl<const N: i32> Defaulted<N> {
226-
$0
227-
}
219+
impl<const N: i32> Defaulted<N> {$0}
228220
"#,
229221
);
230222
}
@@ -254,8 +246,7 @@ mod tests {
254246
impl<T> Struct<T>
255247
where
256248
T: Trait,
257-
{
258-
$0
249+
{$0
259250
}
260251
"#,
261252
);
@@ -285,9 +276,7 @@ mod tests {
285276
r#"
286277
struct Foo {}
287278
288-
impl $0 for Foo {
289-
290-
}
279+
impl ${0:_} for Foo {}
291280
"#,
292281
);
293282
}
@@ -302,9 +291,7 @@ mod tests {
302291
r#"
303292
struct Foo<T: Clone> {}
304293
305-
impl<T: Clone> $0 for Foo<T> {
306-
307-
}
294+
impl<T: Clone> ${0:_} for Foo<T> {}
308295
"#,
309296
);
310297
}
@@ -319,9 +306,7 @@ mod tests {
319306
r#"
320307
struct Foo<'a, T: Foo<'a>> {}
321308
322-
impl<'a, T: Foo<'a>> $0 for Foo<'a, T> {
323-
324-
}
309+
impl<'a, T: Foo<'a>> ${0:_} for Foo<'a, T> {}
325310
"#,
326311
);
327312
}
@@ -339,9 +324,7 @@ mod tests {
339324
struct Foo<'a, T: Foo<'a>> {}
340325
341326
#[cfg(feature = "foo")]
342-
impl<'a, T: Foo<'a>> $0 for Foo<'a, T> {
343-
344-
}
327+
impl<'a, T: Foo<'a>> ${0:_} for Foo<'a, T> {}
345328
"#,
346329
);
347330
}
@@ -356,9 +339,7 @@ mod tests {
356339
r#"
357340
struct Defaulted<T = i32> {}
358341
359-
impl<T> $0 for Defaulted<T> {
360-
361-
}
342+
impl<T> ${0:_} for Defaulted<T> {}
362343
"#,
363344
);
364345
}
@@ -373,9 +354,7 @@ mod tests {
373354
r#"
374355
struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {}
375356
376-
impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> $0 for Defaulted<'a, 'b, T, S> {
377-
378-
}
357+
impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> ${0:_} for Defaulted<'a, 'b, T, S> {}
379358
"#,
380359
);
381360
}
@@ -390,9 +369,7 @@ mod tests {
390369
r#"
391370
struct Defaulted<const N: i32 = 0> {}
392371
393-
impl<const N: i32> $0 for Defaulted<N> {
394-
395-
}
372+
impl<const N: i32> ${0:_} for Defaulted<N> {}
396373
"#,
397374
);
398375
}
@@ -419,11 +396,10 @@ mod tests {
419396
inner: T,
420397
}
421398
422-
impl<T> $0 for Struct<T>
399+
impl<T> ${0:_} for Struct<T>
423400
where
424401
T: Trait,
425402
{
426-
427403
}
428404
"#,
429405
);

crates/ide-assists/src/tests/generated.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,9 +1513,7 @@ struct Ctx<T: Clone> {
15131513
data: T,
15141514
}
15151515
1516-
impl<T: Clone> Ctx<T> {
1517-
$0
1518-
}
1516+
impl<T: Clone> Ctx<T> {$0}
15191517
"#####,
15201518
)
15211519
}
@@ -1702,9 +1700,7 @@ struct Ctx<T: Clone> {
17021700
data: T,
17031701
}
17041702
1705-
impl<T: Clone> $0 for Ctx<T> {
1706-
1707-
}
1703+
impl<T: Clone> ${0:_} for Ctx<T> {}
17081704
"#####,
17091705
)
17101706
}

0 commit comments

Comments
 (0)