diff options
author | Conrad Ludgate <[email protected]> | 2021-03-02 14:28:53 +0000 |
---|---|---|
committer | Conrad Ludgate <[email protected]> | 2021-03-02 14:30:11 +0000 |
commit | d4fad2be8de4906ac00c373e53bb9ac593d61429 (patch) | |
tree | 792754ed2233241d438c7fee642b060b734f413f /crates/ide_assists/src/handlers/add_turbo_fish.rs | |
parent | 4a36129c7a018828548e2eddebdd49cdb7d6879d (diff) |
refactor: re-use add_turbo_fish function
Diffstat (limited to 'crates/ide_assists/src/handlers/add_turbo_fish.rs')
-rw-r--r-- | crates/ide_assists/src/handlers/add_turbo_fish.rs | 138 |
1 files changed, 137 insertions, 1 deletions
diff --git a/crates/ide_assists/src/handlers/add_turbo_fish.rs b/crates/ide_assists/src/handlers/add_turbo_fish.rs index 8e9ea4fad..f18e3edf9 100644 --- a/crates/ide_assists/src/handlers/add_turbo_fish.rs +++ b/crates/ide_assists/src/handlers/add_turbo_fish.rs | |||
@@ -31,11 +31,13 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<( | |||
31 | return None; | 31 | return None; |
32 | } | 32 | } |
33 | mark::hit!(add_turbo_fish_after_call); | 33 | mark::hit!(add_turbo_fish_after_call); |
34 | mark::hit!(add_type_ascription_after_call); | ||
34 | arg_list.l_paren_token()?.prev_token().filter(|it| it.kind() == SyntaxKind::IDENT) | 35 | arg_list.l_paren_token()?.prev_token().filter(|it| it.kind() == SyntaxKind::IDENT) |
35 | })?; | 36 | })?; |
36 | let next_token = ident.next_token()?; | 37 | let next_token = ident.next_token()?; |
37 | if next_token.kind() == T![::] { | 38 | if next_token.kind() == T![::] { |
38 | mark::hit!(add_turbo_fish_one_fish_is_enough); | 39 | mark::hit!(add_turbo_fish_one_fish_is_enough); |
40 | mark::hit!(add_type_ascription_turbofished); | ||
39 | return None; | 41 | return None; |
40 | } | 42 | } |
41 | let name_ref = ast::NameRef::cast(ident.parent())?; | 43 | let name_ref = ast::NameRef::cast(ident.parent())?; |
@@ -50,8 +52,27 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<( | |||
50 | let generics = hir::GenericDef::Function(fun).params(ctx.sema.db); | 52 | let generics = hir::GenericDef::Function(fun).params(ctx.sema.db); |
51 | if generics.is_empty() { | 53 | if generics.is_empty() { |
52 | mark::hit!(add_turbo_fish_non_generic); | 54 | mark::hit!(add_turbo_fish_non_generic); |
55 | mark::hit!(add_type_ascription_non_generic); | ||
53 | return None; | 56 | return None; |
54 | } | 57 | } |
58 | |||
59 | if let Some(let_stmt) = ctx.find_node_at_offset::<ast::LetStmt>() { | ||
60 | if let_stmt.colon_token().is_none() { | ||
61 | let type_pos = let_stmt.pat()?.syntax().last_token()?.text_range().end(); | ||
62 | acc.add( | ||
63 | AssistId("add_type_ascription", AssistKind::RefactorRewrite), | ||
64 | "Add `: _` before assignment operator", | ||
65 | ident.text_range(), | ||
66 | |builder| match ctx.config.snippet_cap { | ||
67 | Some(cap) => builder.insert_snippet(cap, type_pos, ": ${0:_}"), | ||
68 | None => builder.insert(type_pos, ": _"), | ||
69 | }, | ||
70 | )? | ||
71 | } else { | ||
72 | mark::hit!(add_type_ascription_already_typed); | ||
73 | } | ||
74 | } | ||
75 | |||
55 | acc.add( | 76 | acc.add( |
56 | AssistId("add_turbo_fish", AssistKind::RefactorRewrite), | 77 | AssistId("add_turbo_fish", AssistKind::RefactorRewrite), |
57 | "Add `::<>`", | 78 | "Add `::<>`", |
@@ -65,7 +86,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<( | |||
65 | 86 | ||
66 | #[cfg(test)] | 87 | #[cfg(test)] |
67 | mod tests { | 88 | mod tests { |
68 | use crate::tests::{check_assist, check_assist_not_applicable}; | 89 | use crate::tests::{check_assist, check_assist_by_label, check_assist_not_applicable}; |
69 | 90 | ||
70 | use super::*; | 91 | use super::*; |
71 | use test_utils::mark; | 92 | use test_utils::mark; |
@@ -161,4 +182,119 @@ fn main() { | |||
161 | "#, | 182 | "#, |
162 | ); | 183 | ); |
163 | } | 184 | } |
185 | |||
186 | #[test] | ||
187 | fn add_type_ascription_function() { | ||
188 | check_assist_by_label( | ||
189 | add_turbo_fish, | ||
190 | r#" | ||
191 | fn make<T>() -> T {} | ||
192 | fn main() { | ||
193 | let x = make$0(); | ||
194 | } | ||
195 | "#, | ||
196 | r#" | ||
197 | fn make<T>() -> T {} | ||
198 | fn main() { | ||
199 | let x: ${0:_} = make(); | ||
200 | } | ||
201 | "#, | ||
202 | "Add `: _` before assignment operator", | ||
203 | ); | ||
204 | } | ||
205 | |||
206 | #[test] | ||
207 | fn add_type_ascription_after_call() { | ||
208 | mark::check!(add_type_ascription_after_call); | ||
209 | check_assist_by_label( | ||
210 | add_turbo_fish, | ||
211 | r#" | ||
212 | fn make<T>() -> T {} | ||
213 | fn main() { | ||
214 | let x = make()$0; | ||
215 | } | ||
216 | "#, | ||
217 | r#" | ||
218 | fn make<T>() -> T {} | ||
219 | fn main() { | ||
220 | let x: ${0:_} = make(); | ||
221 | } | ||
222 | "#, | ||
223 | "Add `: _` before assignment operator", | ||
224 | ); | ||
225 | } | ||
226 | |||
227 | #[test] | ||
228 | fn add_type_ascription_method() { | ||
229 | check_assist_by_label( | ||
230 | add_turbo_fish, | ||
231 | r#" | ||
232 | struct S; | ||
233 | impl S { | ||
234 | fn make<T>(&self) -> T {} | ||
235 | } | ||
236 | fn main() { | ||
237 | let x = S.make$0(); | ||
238 | } | ||
239 | "#, | ||
240 | r#" | ||
241 | struct S; | ||
242 | impl S { | ||
243 | fn make<T>(&self) -> T {} | ||
244 | } | ||
245 | fn main() { | ||
246 | let x: ${0:_} = S.make(); | ||
247 | } | ||
248 | "#, | ||
249 | "Add `: _` before assignment operator", | ||
250 | ); | ||
251 | } | ||
252 | |||
253 | #[test] | ||
254 | fn add_type_ascription_turbofished() { | ||
255 | mark::check!(add_type_ascription_turbofished); | ||
256 | check_assist_not_applicable( | ||
257 | add_turbo_fish, | ||
258 | r#" | ||
259 | fn make<T>() -> T {} | ||
260 | fn main() { | ||
261 | let x = make$0::<()>(); | ||
262 | } | ||
263 | "#, | ||
264 | ); | ||
265 | } | ||
266 | |||
267 | #[test] | ||
268 | fn add_type_ascription_already_typed() { | ||
269 | mark::check!(add_type_ascription_already_typed); | ||
270 | check_assist( | ||
271 | add_turbo_fish, | ||
272 | r#" | ||
273 | fn make<T>() -> T {} | ||
274 | fn main() { | ||
275 | let x: () = make$0(); | ||
276 | } | ||
277 | "#, | ||
278 | r#" | ||
279 | fn make<T>() -> T {} | ||
280 | fn main() { | ||
281 | let x: () = make::<${0:_}>(); | ||
282 | } | ||
283 | "#, | ||
284 | ); | ||
285 | } | ||
286 | |||
287 | #[test] | ||
288 | fn add_type_ascription_non_generic() { | ||
289 | mark::check!(add_type_ascription_non_generic); | ||
290 | check_assist_not_applicable( | ||
291 | add_turbo_fish, | ||
292 | r#" | ||
293 | fn make() -> () {} | ||
294 | fn main() { | ||
295 | let x = make$0(); | ||
296 | } | ||
297 | "#, | ||
298 | ); | ||
299 | } | ||
164 | } | 300 | } |