diff options
Diffstat (limited to 'crates/ra_ide_api/src/completion')
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_path.rs | 523 |
1 files changed, 366 insertions, 157 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index b42b7c458..a41cab359 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs | |||
@@ -74,10 +74,11 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
74 | mod tests { | 74 | mod tests { |
75 | use test_utils::covers; | 75 | use test_utils::covers; |
76 | 76 | ||
77 | use crate::completion::{CompletionKind, check_completion, do_completion}; | 77 | use crate::completion::{CompletionKind, do_completion, CompletionItem}; |
78 | use insta::assert_debug_snapshot_matches; | ||
78 | 79 | ||
79 | fn check_reference_completion(code: &str, expected_completions: &str) { | 80 | fn do_reference_completion(code: &str) -> Vec<CompletionItem> { |
80 | check_completion(code, expected_completions, CompletionKind::Reference); | 81 | do_completion(code, CompletionKind::Reference) |
81 | } | 82 | } |
82 | 83 | ||
83 | #[test] | 84 | #[test] |
@@ -115,227 +116,435 @@ mod tests { | |||
115 | 116 | ||
116 | #[test] | 117 | #[test] |
117 | fn completes_mod_with_docs() { | 118 | fn completes_mod_with_docs() { |
118 | check_reference_completion( | 119 | assert_debug_snapshot_matches!( |
119 | "mod_with_docs", | 120 | do_reference_completion( |
120 | r" | 121 | r" |
121 | use self::my<|>; | 122 | use self::my<|>; |
122 | 123 | ||
123 | /// Some simple | 124 | /// Some simple |
124 | /// docs describing `mod my`. | 125 | /// docs describing `mod my`. |
125 | mod my { | 126 | mod my { |
126 | struct Bar; | 127 | struct Bar; |
127 | } | 128 | } |
128 | ", | 129 | " |
130 | ), | ||
131 | @r###"[ | ||
132 | CompletionItem { | ||
133 | label: "my", | ||
134 | source_range: [27; 29), | ||
135 | delete: [27; 29), | ||
136 | insert: "my", | ||
137 | kind: Module, | ||
138 | documentation: Documentation( | ||
139 | "Some simple\ndocs describing `mod my`.", | ||
140 | ), | ||
141 | }, | ||
142 | ]"### | ||
129 | ); | 143 | ); |
130 | } | 144 | } |
131 | 145 | ||
132 | #[test] | 146 | #[test] |
133 | fn completes_use_item_starting_with_self() { | 147 | fn completes_use_item_starting_with_self() { |
134 | check_reference_completion( | 148 | assert_debug_snapshot_matches!( |
135 | "use_item_starting_with_self", | 149 | do_reference_completion( |
136 | r" | 150 | r" |
137 | use self::m::<|>; | 151 | use self::m::<|>; |
138 | 152 | ||
139 | mod m { | 153 | mod m { |
140 | struct Bar; | 154 | struct Bar; |
141 | } | 155 | } |
142 | ", | 156 | " |
157 | ), | ||
158 | @r###"[ | ||
159 | CompletionItem { | ||
160 | label: "Bar", | ||
161 | source_range: [30; 30), | ||
162 | delete: [30; 30), | ||
163 | insert: "Bar", | ||
164 | kind: Struct, | ||
165 | }, | ||
166 | ]"### | ||
143 | ); | 167 | ); |
144 | } | 168 | } |
145 | 169 | ||
146 | #[test] | 170 | #[test] |
147 | fn completes_use_item_starting_with_crate() { | 171 | fn completes_use_item_starting_with_crate() { |
148 | check_reference_completion( | 172 | assert_debug_snapshot_matches!( |
149 | "use_item_starting_with_crate", | 173 | do_reference_completion( |
150 | " | 174 | " |
151 | //- /lib.rs | 175 | //- /lib.rs |
152 | mod foo; | 176 | mod foo; |
153 | struct Spam; | 177 | struct Spam; |
154 | //- /foo.rs | 178 | //- /foo.rs |
155 | use crate::Sp<|> | 179 | use crate::Sp<|> |
156 | ", | 180 | " |
181 | ), | ||
182 | @r###"[ | ||
183 | CompletionItem { | ||
184 | label: "Spam", | ||
185 | source_range: [11; 13), | ||
186 | delete: [11; 13), | ||
187 | insert: "Spam", | ||
188 | kind: Struct, | ||
189 | }, | ||
190 | CompletionItem { | ||
191 | label: "foo", | ||
192 | source_range: [11; 13), | ||
193 | delete: [11; 13), | ||
194 | insert: "foo", | ||
195 | kind: Module, | ||
196 | }, | ||
197 | ]"### | ||
157 | ); | 198 | ); |
158 | } | 199 | } |
159 | 200 | ||
160 | #[test] | 201 | #[test] |
161 | fn completes_nested_use_tree() { | 202 | fn completes_nested_use_tree() { |
162 | check_reference_completion( | 203 | assert_debug_snapshot_matches!( |
163 | "nested_use_tree", | 204 | do_reference_completion( |
164 | " | 205 | " |
165 | //- /lib.rs | 206 | //- /lib.rs |
166 | mod foo; | 207 | mod foo; |
167 | struct Spam; | 208 | struct Spam; |
168 | //- /foo.rs | 209 | //- /foo.rs |
169 | use crate::{Sp<|>}; | 210 | use crate::{Sp<|>}; |
170 | ", | 211 | " |
212 | ), | ||
213 | @r###"[ | ||
214 | CompletionItem { | ||
215 | label: "Spam", | ||
216 | source_range: [12; 14), | ||
217 | delete: [12; 14), | ||
218 | insert: "Spam", | ||
219 | kind: Struct, | ||
220 | }, | ||
221 | CompletionItem { | ||
222 | label: "foo", | ||
223 | source_range: [12; 14), | ||
224 | delete: [12; 14), | ||
225 | insert: "foo", | ||
226 | kind: Module, | ||
227 | }, | ||
228 | ]"### | ||
171 | ); | 229 | ); |
172 | } | 230 | } |
173 | 231 | ||
174 | #[test] | 232 | #[test] |
175 | fn completes_deeply_nested_use_tree() { | 233 | fn completes_deeply_nested_use_tree() { |
176 | check_reference_completion( | 234 | assert_debug_snapshot_matches!( |
177 | "deeply_nested_use_tree", | 235 | do_reference_completion( |
178 | " | 236 | " |
179 | //- /lib.rs | 237 | //- /lib.rs |
180 | mod foo; | 238 | mod foo; |
181 | pub mod bar { | 239 | pub mod bar { |
182 | pub mod baz { | 240 | pub mod baz { |
183 | pub struct Spam; | 241 | pub struct Spam; |
242 | } | ||
184 | } | 243 | } |
185 | } | 244 | //- /foo.rs |
186 | //- /foo.rs | 245 | use crate::{bar::{baz::Sp<|>}}; |
187 | use crate::{bar::{baz::Sp<|>}}; | 246 | " |
188 | ", | 247 | ), |
248 | @r###"[ | ||
249 | CompletionItem { | ||
250 | label: "Spam", | ||
251 | source_range: [23; 25), | ||
252 | delete: [23; 25), | ||
253 | insert: "Spam", | ||
254 | kind: Struct, | ||
255 | }, | ||
256 | ]"### | ||
189 | ); | 257 | ); |
190 | } | 258 | } |
191 | 259 | ||
192 | #[test] | 260 | #[test] |
193 | fn completes_enum_variant() { | 261 | fn completes_enum_variant() { |
194 | check_reference_completion( | 262 | assert_debug_snapshot_matches!( |
195 | "enum_variant", | 263 | do_reference_completion( |
196 | " | 264 | " |
197 | //- /lib.rs | 265 | //- /lib.rs |
198 | /// An enum | 266 | /// An enum |
199 | enum E { | 267 | enum E { |
200 | /// Foo Variant | 268 | /// Foo Variant |
201 | Foo, | 269 | Foo, |
202 | /// Bar Variant with i32 | 270 | /// Bar Variant with i32 |
203 | Bar(i32) | 271 | Bar(i32) |
204 | } | 272 | } |
205 | fn foo() { let _ = E::<|> } | 273 | fn foo() { let _ = E::<|> } |
206 | ", | 274 | " |
275 | ), | ||
276 | @r###"[ | ||
277 | CompletionItem { | ||
278 | label: "Bar", | ||
279 | source_range: [116; 116), | ||
280 | delete: [116; 116), | ||
281 | insert: "Bar", | ||
282 | kind: EnumVariant, | ||
283 | detail: "(i32)", | ||
284 | documentation: Documentation( | ||
285 | "Bar Variant with i32", | ||
286 | ), | ||
287 | }, | ||
288 | CompletionItem { | ||
289 | label: "Foo", | ||
290 | source_range: [116; 116), | ||
291 | delete: [116; 116), | ||
292 | insert: "Foo", | ||
293 | kind: EnumVariant, | ||
294 | detail: "()", | ||
295 | documentation: Documentation( | ||
296 | "Foo Variant", | ||
297 | ), | ||
298 | }, | ||
299 | ]"### | ||
207 | ); | 300 | ); |
208 | } | 301 | } |
209 | 302 | ||
210 | #[test] | 303 | #[test] |
211 | fn completes_enum_variant_with_details() { | 304 | fn completes_enum_variant_with_details() { |
212 | check_reference_completion( | 305 | assert_debug_snapshot_matches!( |
213 | "enum_variant_with_details", | 306 | do_reference_completion( |
214 | " | 307 | " |
215 | //- /lib.rs | 308 | //- /lib.rs |
216 | struct S { field: u32 } | 309 | struct S { field: u32 } |
217 | /// An enum | 310 | /// An enum |
218 | enum E { | 311 | enum E { |
219 | /// Foo Variant (empty) | 312 | /// Foo Variant (empty) |
220 | Foo, | 313 | Foo, |
221 | /// Bar Variant with i32 and u32 | 314 | /// Bar Variant with i32 and u32 |
222 | Bar(i32, u32), | 315 | Bar(i32, u32), |
223 | /// | 316 | /// |
224 | S(S), | 317 | S(S), |
225 | } | 318 | } |
226 | fn foo() { let _ = E::<|> } | 319 | fn foo() { let _ = E::<|> } |
227 | ", | 320 | " |
321 | ), | ||
322 | @r###"[ | ||
323 | CompletionItem { | ||
324 | label: "Bar", | ||
325 | source_range: [180; 180), | ||
326 | delete: [180; 180), | ||
327 | insert: "Bar", | ||
328 | kind: EnumVariant, | ||
329 | detail: "(i32, u32)", | ||
330 | documentation: Documentation( | ||
331 | "Bar Variant with i32 and u32", | ||
332 | ), | ||
333 | }, | ||
334 | CompletionItem { | ||
335 | label: "Foo", | ||
336 | source_range: [180; 180), | ||
337 | delete: [180; 180), | ||
338 | insert: "Foo", | ||
339 | kind: EnumVariant, | ||
340 | detail: "()", | ||
341 | documentation: Documentation( | ||
342 | "Foo Variant (empty)", | ||
343 | ), | ||
344 | }, | ||
345 | CompletionItem { | ||
346 | label: "S", | ||
347 | source_range: [180; 180), | ||
348 | delete: [180; 180), | ||
349 | insert: "S", | ||
350 | kind: EnumVariant, | ||
351 | detail: "(S)", | ||
352 | documentation: Documentation( | ||
353 | "", | ||
354 | ), | ||
355 | }, | ||
356 | ]"### | ||
228 | ); | 357 | ); |
229 | } | 358 | } |
230 | 359 | ||
231 | #[test] | 360 | #[test] |
232 | fn completes_struct_associated_method() { | 361 | fn completes_struct_associated_method() { |
233 | check_reference_completion( | 362 | assert_debug_snapshot_matches!( |
234 | "struct_associated_method", | 363 | do_reference_completion( |
235 | " | 364 | " |
236 | //- /lib.rs | 365 | //- /lib.rs |
237 | /// A Struct | 366 | /// A Struct |
238 | struct S; | 367 | struct S; |
239 | 368 | ||
240 | impl S { | 369 | impl S { |
241 | /// An associated method | 370 | /// An associated method |
242 | fn m() { } | 371 | fn m() { } |
243 | } | 372 | } |
244 | 373 | ||
245 | fn foo() { let _ = S::<|> } | 374 | fn foo() { let _ = S::<|> } |
246 | ", | 375 | " |
376 | ), | ||
377 | @r###"[ | ||
378 | CompletionItem { | ||
379 | label: "m", | ||
380 | source_range: [100; 100), | ||
381 | delete: [100; 100), | ||
382 | insert: "m()$0", | ||
383 | kind: Function, | ||
384 | detail: "fn m()", | ||
385 | documentation: Documentation( | ||
386 | "An associated method", | ||
387 | ), | ||
388 | }, | ||
389 | ]"### | ||
247 | ); | 390 | ); |
248 | } | 391 | } |
249 | 392 | ||
250 | #[test] | 393 | #[test] |
251 | fn completes_struct_associated_const() { | 394 | fn completes_struct_associated_const() { |
252 | check_reference_completion( | 395 | assert_debug_snapshot_matches!( |
253 | "struct_associated_const", | 396 | do_reference_completion( |
254 | " | 397 | " |
255 | //- /lib.rs | 398 | //- /lib.rs |
256 | /// A Struct | 399 | /// A Struct |
257 | struct S; | 400 | struct S; |
258 | 401 | ||
259 | impl S { | 402 | impl S { |
260 | /// An associated const | 403 | /// An associated const |
261 | const C: i32 = 42; | 404 | const C: i32 = 42; |
262 | } | 405 | } |
263 | 406 | ||
264 | fn foo() { let _ = S::<|> } | 407 | fn foo() { let _ = S::<|> } |
265 | ", | 408 | " |
409 | ), | ||
410 | @r###"[ | ||
411 | CompletionItem { | ||
412 | label: "C", | ||
413 | source_range: [107; 107), | ||
414 | delete: [107; 107), | ||
415 | insert: "C", | ||
416 | kind: Const, | ||
417 | detail: "const C: i32 = 42;", | ||
418 | documentation: Documentation( | ||
419 | "An associated const", | ||
420 | ), | ||
421 | }, | ||
422 | ]"### | ||
266 | ); | 423 | ); |
267 | } | 424 | } |
268 | 425 | ||
269 | #[test] | 426 | #[test] |
270 | fn completes_struct_associated_type() { | 427 | fn completes_struct_associated_type() { |
271 | check_reference_completion( | 428 | assert_debug_snapshot_matches!( |
272 | "struct_associated_type", | 429 | do_reference_completion( |
273 | " | 430 | " |
274 | //- /lib.rs | 431 | //- /lib.rs |
275 | /// A Struct | 432 | /// A Struct |
276 | struct S; | 433 | struct S; |
277 | 434 | ||
278 | impl S { | 435 | impl S { |
279 | /// An associated type | 436 | /// An associated type |
280 | type T = i32; | 437 | type T = i32; |
281 | } | 438 | } |
282 | 439 | ||
283 | fn foo() { let _ = S::<|> } | 440 | fn foo() { let _ = S::<|> } |
284 | ", | 441 | " |
442 | ), | ||
443 | @r###"[ | ||
444 | CompletionItem { | ||
445 | label: "T", | ||
446 | source_range: [101; 101), | ||
447 | delete: [101; 101), | ||
448 | insert: "T", | ||
449 | kind: TypeAlias, | ||
450 | detail: "type T = i32;", | ||
451 | documentation: Documentation( | ||
452 | "An associated type", | ||
453 | ), | ||
454 | }, | ||
455 | ]"### | ||
285 | ); | 456 | ); |
286 | } | 457 | } |
287 | 458 | ||
288 | #[test] | 459 | #[test] |
289 | fn completes_enum_associated_method() { | 460 | fn completes_enum_associated_method() { |
290 | check_reference_completion( | 461 | assert_debug_snapshot_matches!( |
291 | "enum_associated_method", | 462 | do_reference_completion( |
292 | " | 463 | " |
293 | //- /lib.rs | 464 | //- /lib.rs |
294 | /// An enum | 465 | /// An enum |
295 | enum S {}; | 466 | enum S {}; |
296 | 467 | ||
297 | impl S { | 468 | impl S { |
298 | /// An associated method | 469 | /// An associated method |
299 | fn m() { } | 470 | fn m() { } |
300 | } | 471 | } |
301 | 472 | ||
302 | fn foo() { let _ = S::<|> } | 473 | fn foo() { let _ = S::<|> } |
303 | ", | 474 | " |
475 | ), | ||
476 | @r###"[ | ||
477 | CompletionItem { | ||
478 | label: "m", | ||
479 | source_range: [100; 100), | ||
480 | delete: [100; 100), | ||
481 | insert: "m()$0", | ||
482 | kind: Function, | ||
483 | detail: "fn m()", | ||
484 | documentation: Documentation( | ||
485 | "An associated method", | ||
486 | ), | ||
487 | }, | ||
488 | ]"### | ||
304 | ); | 489 | ); |
305 | } | 490 | } |
306 | 491 | ||
307 | #[test] | 492 | #[test] |
308 | fn completes_union_associated_method() { | 493 | fn completes_union_associated_method() { |
309 | check_reference_completion( | 494 | assert_debug_snapshot_matches!( |
310 | "union_associated_method", | 495 | do_reference_completion( |
311 | " | 496 | " |
312 | //- /lib.rs | 497 | //- /lib.rs |
313 | /// A union | 498 | /// A union |
314 | union U {}; | 499 | union U {}; |
315 | 500 | ||
316 | impl U { | 501 | impl U { |
317 | /// An associated method | 502 | /// An associated method |
318 | fn m() { } | 503 | fn m() { } |
319 | } | 504 | } |
320 | 505 | ||
321 | fn foo() { let _ = U::<|> } | 506 | fn foo() { let _ = U::<|> } |
322 | ", | 507 | " |
508 | ), | ||
509 | @r###"[ | ||
510 | CompletionItem { | ||
511 | label: "m", | ||
512 | source_range: [101; 101), | ||
513 | delete: [101; 101), | ||
514 | insert: "m()$0", | ||
515 | kind: Function, | ||
516 | detail: "fn m()", | ||
517 | documentation: Documentation( | ||
518 | "An associated method", | ||
519 | ), | ||
520 | }, | ||
521 | ]"### | ||
323 | ); | 522 | ); |
324 | } | 523 | } |
325 | 524 | ||
326 | #[test] | 525 | #[test] |
327 | fn completes_use_paths_across_crates() { | 526 | fn completes_use_paths_across_crates() { |
328 | check_reference_completion( | 527 | assert_debug_snapshot_matches!( |
329 | "completes_use_paths_across_crates", | 528 | do_reference_completion( |
330 | " | 529 | " |
331 | //- /main.rs | 530 | //- /main.rs |
332 | use foo::<|>; | 531 | use foo::<|>; |
333 | 532 | ||
334 | //- /foo/lib.rs | 533 | //- /foo/lib.rs |
335 | pub mod bar { | 534 | pub mod bar { |
336 | pub struct S; | 535 | pub struct S; |
337 | } | 536 | } |
338 | ", | 537 | " |
538 | ), | ||
539 | @r###"[ | ||
540 | CompletionItem { | ||
541 | label: "bar", | ||
542 | source_range: [9; 9), | ||
543 | delete: [9; 9), | ||
544 | insert: "bar", | ||
545 | kind: Module, | ||
546 | }, | ||
547 | ]"### | ||
339 | ); | 548 | ); |
340 | } | 549 | } |
341 | } | 550 | } |