diff options
Diffstat (limited to 'crates/assists/src/handlers')
-rw-r--r-- | crates/assists/src/handlers/generate_impl.rs | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/crates/assists/src/handlers/generate_impl.rs b/crates/assists/src/handlers/generate_impl.rs index 9989109b5..114974465 100644 --- a/crates/assists/src/handlers/generate_impl.rs +++ b/crates/assists/src/handlers/generate_impl.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use itertools::Itertools; | 1 | use itertools::Itertools; |
2 | use stdx::format_to; | 2 | use stdx::format_to; |
3 | use syntax::ast::{self, AstNode, GenericParamsOwner, NameOwner}; | 3 | use syntax::ast::{self, AstNode, AttrsOwner, GenericParamsOwner, NameOwner}; |
4 | 4 | ||
5 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | 5 | use crate::{AssistContext, AssistId, AssistKind, Assists}; |
6 | 6 | ||
@@ -27,6 +27,7 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<() | |||
27 | let nominal = ctx.find_node_at_offset::<ast::AdtDef>()?; | 27 | let nominal = ctx.find_node_at_offset::<ast::AdtDef>()?; |
28 | let name = nominal.name()?; | 28 | let name = nominal.name()?; |
29 | let target = nominal.syntax().text_range(); | 29 | let target = nominal.syntax().text_range(); |
30 | |||
30 | acc.add( | 31 | acc.add( |
31 | AssistId("generate_impl", AssistKind::Generate), | 32 | AssistId("generate_impl", AssistKind::Generate), |
32 | format!("Generate impl for `{}`", name), | 33 | format!("Generate impl for `{}`", name), |
@@ -35,7 +36,15 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<() | |||
35 | let type_params = nominal.generic_param_list(); | 36 | let type_params = nominal.generic_param_list(); |
36 | let start_offset = nominal.syntax().text_range().end(); | 37 | let start_offset = nominal.syntax().text_range().end(); |
37 | let mut buf = String::new(); | 38 | let mut buf = String::new(); |
38 | buf.push_str("\n\nimpl"); | 39 | buf.push_str("\n\n"); |
40 | nominal | ||
41 | .attrs() | ||
42 | .filter(|attr| { | ||
43 | attr.as_simple_call().map(|(name, _arg)| name == "cfg").unwrap_or(false) | ||
44 | }) | ||
45 | .for_each(|attr| buf.push_str(format!("{}\n", attr.to_string()).as_str())); | ||
46 | |||
47 | buf.push_str("impl"); | ||
39 | if let Some(type_params) = &type_params { | 48 | if let Some(type_params) = &type_params { |
40 | format_to!(buf, "{}", type_params.syntax()); | 49 | format_to!(buf, "{}", type_params.syntax()); |
41 | } | 50 | } |
@@ -91,6 +100,35 @@ mod tests { | |||
91 | "struct Foo<'a, T: Foo<'a>> {<|>}", | 100 | "struct Foo<'a, T: Foo<'a>> {<|>}", |
92 | "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n $0\n}", | 101 | "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n $0\n}", |
93 | ); | 102 | ); |
103 | check_assist( | ||
104 | generate_impl, | ||
105 | r#" | ||
106 | #[cfg(feature = "foo")] | ||
107 | struct Foo<'a, T: Foo<'a>> {<|>}"#, | ||
108 | r#" | ||
109 | #[cfg(feature = "foo")] | ||
110 | struct Foo<'a, T: Foo<'a>> {} | ||
111 | |||
112 | #[cfg(feature = "foo")] | ||
113 | impl<'a, T: Foo<'a>> Foo<'a, T> { | ||
114 | $0 | ||
115 | }"#, | ||
116 | ); | ||
117 | |||
118 | check_assist( | ||
119 | generate_impl, | ||
120 | r#" | ||
121 | #[cfg(not(feature = "foo"))] | ||
122 | struct Foo<'a, T: Foo<'a>> {<|>}"#, | ||
123 | r#" | ||
124 | #[cfg(not(feature = "foo"))] | ||
125 | struct Foo<'a, T: Foo<'a>> {} | ||
126 | |||
127 | #[cfg(not(feature = "foo"))] | ||
128 | impl<'a, T: Foo<'a>> Foo<'a, T> { | ||
129 | $0 | ||
130 | }"#, | ||
131 | ); | ||
94 | } | 132 | } |
95 | 133 | ||
96 | #[test] | 134 | #[test] |