diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-27 18:45:05 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-11-27 18:45:05 +0000 |
commit | 360f6b7bb32d6280ed787075c4a54f4e5b46fcb6 (patch) | |
tree | 4c059427819ef442c785125f48fe83f81f6d667a /crates/ra_ide/src/completion/complete_scope.rs | |
parent | 4946169a96f3d442f463724af481fdb760381ccb (diff) | |
parent | 27b362b05910c81fd5b28f6cd5d2c075311032f9 (diff) |
Merge #2430
2430: rename ra_ide_api -> ra_ide r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_ide/src/completion/complete_scope.rs')
-rw-r--r-- | crates/ra_ide/src/completion/complete_scope.rs | 876 |
1 files changed, 876 insertions, 0 deletions
diff --git a/crates/ra_ide/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs new file mode 100644 index 000000000..d5739b58a --- /dev/null +++ b/crates/ra_ide/src/completion/complete_scope.rs | |||
@@ -0,0 +1,876 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use ra_assists::auto_import_text_edit; | ||
4 | use ra_syntax::{ast, AstNode, SmolStr}; | ||
5 | use ra_text_edit::TextEditBuilder; | ||
6 | use rustc_hash::FxHashMap; | ||
7 | |||
8 | use crate::completion::{CompletionContext, CompletionItem, CompletionKind, Completions}; | ||
9 | |||
10 | pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | ||
11 | if !ctx.is_trivial_path { | ||
12 | return; | ||
13 | } | ||
14 | |||
15 | ctx.analyzer.process_all_names(ctx.db, &mut |name, res| { | ||
16 | acc.add_resolution(ctx, name.to_string(), &res) | ||
17 | }); | ||
18 | |||
19 | // auto-import | ||
20 | // We fetch ident from the original file, because we need to pre-filter auto-imports | ||
21 | if ast::NameRef::cast(ctx.token.parent()).is_some() { | ||
22 | let import_resolver = ImportResolver::new(); | ||
23 | let import_names = import_resolver.all_names(ctx.token.text()); | ||
24 | import_names.into_iter().for_each(|(name, path)| { | ||
25 | let edit = { | ||
26 | let mut builder = TextEditBuilder::default(); | ||
27 | builder.replace(ctx.source_range(), name.to_string()); | ||
28 | auto_import_text_edit( | ||
29 | &ctx.token.parent(), | ||
30 | &ctx.token.parent(), | ||
31 | &path, | ||
32 | &mut builder, | ||
33 | ); | ||
34 | builder.finish() | ||
35 | }; | ||
36 | |||
37 | // Hack: copied this check form conv.rs beacause auto import can produce edits | ||
38 | // that invalidate assert in conv_with. | ||
39 | if edit | ||
40 | .as_atoms() | ||
41 | .iter() | ||
42 | .filter(|atom| !ctx.source_range().is_subrange(&atom.delete)) | ||
43 | .all(|atom| ctx.source_range().intersection(&atom.delete).is_none()) | ||
44 | { | ||
45 | CompletionItem::new( | ||
46 | CompletionKind::Reference, | ||
47 | ctx.source_range(), | ||
48 | build_import_label(&name, &path), | ||
49 | ) | ||
50 | .text_edit(edit) | ||
51 | .add_to(acc); | ||
52 | } | ||
53 | }); | ||
54 | } | ||
55 | } | ||
56 | |||
57 | fn build_import_label(name: &str, path: &[SmolStr]) -> String { | ||
58 | let mut buf = String::with_capacity(64); | ||
59 | buf.push_str(name); | ||
60 | buf.push_str(" ("); | ||
61 | fmt_import_path(path, &mut buf); | ||
62 | buf.push_str(")"); | ||
63 | buf | ||
64 | } | ||
65 | |||
66 | fn fmt_import_path(path: &[SmolStr], buf: &mut String) { | ||
67 | let mut segments = path.iter(); | ||
68 | if let Some(s) = segments.next() { | ||
69 | buf.push_str(&s); | ||
70 | } | ||
71 | for s in segments { | ||
72 | buf.push_str("::"); | ||
73 | buf.push_str(&s); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | #[derive(Debug, Clone, Default)] | ||
78 | pub(crate) struct ImportResolver { | ||
79 | // todo: use fst crate or something like that | ||
80 | dummy_names: Vec<(SmolStr, Vec<SmolStr>)>, | ||
81 | } | ||
82 | |||
83 | impl ImportResolver { | ||
84 | pub(crate) fn new() -> Self { | ||
85 | let dummy_names = vec![ | ||
86 | (SmolStr::new("fmt"), vec![SmolStr::new("std"), SmolStr::new("fmt")]), | ||
87 | (SmolStr::new("io"), vec![SmolStr::new("std"), SmolStr::new("io")]), | ||
88 | (SmolStr::new("iter"), vec![SmolStr::new("std"), SmolStr::new("iter")]), | ||
89 | (SmolStr::new("hash"), vec![SmolStr::new("std"), SmolStr::new("hash")]), | ||
90 | ( | ||
91 | SmolStr::new("Debug"), | ||
92 | vec![SmolStr::new("std"), SmolStr::new("fmt"), SmolStr::new("Debug")], | ||
93 | ), | ||
94 | ( | ||
95 | SmolStr::new("Display"), | ||
96 | vec![SmolStr::new("std"), SmolStr::new("fmt"), SmolStr::new("Display")], | ||
97 | ), | ||
98 | ( | ||
99 | SmolStr::new("Hash"), | ||
100 | vec![SmolStr::new("std"), SmolStr::new("hash"), SmolStr::new("Hash")], | ||
101 | ), | ||
102 | ( | ||
103 | SmolStr::new("Hasher"), | ||
104 | vec![SmolStr::new("std"), SmolStr::new("hash"), SmolStr::new("Hasher")], | ||
105 | ), | ||
106 | ( | ||
107 | SmolStr::new("Iterator"), | ||
108 | vec![SmolStr::new("std"), SmolStr::new("iter"), SmolStr::new("Iterator")], | ||
109 | ), | ||
110 | ]; | ||
111 | |||
112 | ImportResolver { dummy_names } | ||
113 | } | ||
114 | |||
115 | // Returns a map of importable items filtered by name. | ||
116 | // The map associates item name with its full path. | ||
117 | // todo: should return Resolutions | ||
118 | pub(crate) fn all_names(&self, name: &str) -> FxHashMap<SmolStr, Vec<SmolStr>> { | ||
119 | if name.len() > 1 { | ||
120 | self.dummy_names.iter().filter(|(n, _)| n.contains(name)).cloned().collect() | ||
121 | } else { | ||
122 | FxHashMap::default() | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | |||
127 | #[cfg(test)] | ||
128 | mod tests { | ||
129 | use crate::completion::{do_completion, CompletionItem, CompletionKind}; | ||
130 | use insta::assert_debug_snapshot; | ||
131 | |||
132 | fn do_reference_completion(code: &str) -> Vec<CompletionItem> { | ||
133 | do_completion(code, CompletionKind::Reference) | ||
134 | } | ||
135 | |||
136 | #[test] | ||
137 | fn completes_bindings_from_let() { | ||
138 | assert_debug_snapshot!( | ||
139 | do_reference_completion( | ||
140 | r" | ||
141 | fn quux(x: i32) { | ||
142 | let y = 92; | ||
143 | 1 + <|>; | ||
144 | let z = (); | ||
145 | } | ||
146 | " | ||
147 | ), | ||
148 | @r###" | ||
149 | [ | ||
150 | CompletionItem { | ||
151 | label: "quux(…)", | ||
152 | source_range: [91; 91), | ||
153 | delete: [91; 91), | ||
154 | insert: "quux($0)", | ||
155 | kind: Function, | ||
156 | lookup: "quux", | ||
157 | detail: "fn quux(x: i32)", | ||
158 | }, | ||
159 | CompletionItem { | ||
160 | label: "x", | ||
161 | source_range: [91; 91), | ||
162 | delete: [91; 91), | ||
163 | insert: "x", | ||
164 | kind: Binding, | ||
165 | detail: "i32", | ||
166 | }, | ||
167 | CompletionItem { | ||
168 | label: "y", | ||
169 | source_range: [91; 91), | ||
170 | delete: [91; 91), | ||
171 | insert: "y", | ||
172 | kind: Binding, | ||
173 | detail: "i32", | ||
174 | }, | ||
175 | ] | ||
176 | "### | ||
177 | ); | ||
178 | } | ||
179 | |||
180 | #[test] | ||
181 | fn completes_bindings_from_if_let() { | ||
182 | assert_debug_snapshot!( | ||
183 | do_reference_completion( | ||
184 | r" | ||
185 | fn quux() { | ||
186 | if let Some(x) = foo() { | ||
187 | let y = 92; | ||
188 | }; | ||
189 | if let Some(a) = bar() { | ||
190 | let b = 62; | ||
191 | 1 + <|> | ||
192 | } | ||
193 | } | ||
194 | " | ||
195 | ), | ||
196 | @r###" | ||
197 | [ | ||
198 | CompletionItem { | ||
199 | label: "a", | ||
200 | source_range: [242; 242), | ||
201 | delete: [242; 242), | ||
202 | insert: "a", | ||
203 | kind: Binding, | ||
204 | }, | ||
205 | CompletionItem { | ||
206 | label: "b", | ||
207 | source_range: [242; 242), | ||
208 | delete: [242; 242), | ||
209 | insert: "b", | ||
210 | kind: Binding, | ||
211 | detail: "i32", | ||
212 | }, | ||
213 | CompletionItem { | ||
214 | label: "quux()", | ||
215 | source_range: [242; 242), | ||
216 | delete: [242; 242), | ||
217 | insert: "quux()$0", | ||
218 | kind: Function, | ||
219 | lookup: "quux", | ||
220 | detail: "fn quux()", | ||
221 | }, | ||
222 | ] | ||
223 | "### | ||
224 | ); | ||
225 | } | ||
226 | |||
227 | #[test] | ||
228 | fn completes_bindings_from_for() { | ||
229 | assert_debug_snapshot!( | ||
230 | do_reference_completion( | ||
231 | r" | ||
232 | fn quux() { | ||
233 | for x in &[1, 2, 3] { | ||
234 | <|> | ||
235 | } | ||
236 | } | ||
237 | " | ||
238 | ), | ||
239 | @r###" | ||
240 | [ | ||
241 | CompletionItem { | ||
242 | label: "quux()", | ||
243 | source_range: [95; 95), | ||
244 | delete: [95; 95), | ||
245 | insert: "quux()$0", | ||
246 | kind: Function, | ||
247 | lookup: "quux", | ||
248 | detail: "fn quux()", | ||
249 | }, | ||
250 | CompletionItem { | ||
251 | label: "x", | ||
252 | source_range: [95; 95), | ||
253 | delete: [95; 95), | ||
254 | insert: "x", | ||
255 | kind: Binding, | ||
256 | }, | ||
257 | ] | ||
258 | "### | ||
259 | ); | ||
260 | } | ||
261 | |||
262 | #[test] | ||
263 | fn completes_generic_params() { | ||
264 | assert_debug_snapshot!( | ||
265 | do_reference_completion( | ||
266 | r" | ||
267 | fn quux<T>() { | ||
268 | <|> | ||
269 | } | ||
270 | " | ||
271 | ), | ||
272 | @r###" | ||
273 | [ | ||
274 | CompletionItem { | ||
275 | label: "T", | ||
276 | source_range: [52; 52), | ||
277 | delete: [52; 52), | ||
278 | insert: "T", | ||
279 | kind: TypeParam, | ||
280 | }, | ||
281 | CompletionItem { | ||
282 | label: "quux()", | ||
283 | source_range: [52; 52), | ||
284 | delete: [52; 52), | ||
285 | insert: "quux()$0", | ||
286 | kind: Function, | ||
287 | lookup: "quux", | ||
288 | detail: "fn quux<T>()", | ||
289 | }, | ||
290 | ] | ||
291 | "### | ||
292 | ); | ||
293 | } | ||
294 | |||
295 | #[test] | ||
296 | fn completes_generic_params_in_struct() { | ||
297 | assert_debug_snapshot!( | ||
298 | do_reference_completion( | ||
299 | r" | ||
300 | struct X<T> { | ||
301 | x: <|> | ||
302 | } | ||
303 | " | ||
304 | ), | ||
305 | @r###" | ||
306 | [ | ||
307 | CompletionItem { | ||
308 | label: "Self", | ||
309 | source_range: [54; 54), | ||
310 | delete: [54; 54), | ||
311 | insert: "Self", | ||
312 | kind: TypeParam, | ||
313 | }, | ||
314 | CompletionItem { | ||
315 | label: "T", | ||
316 | source_range: [54; 54), | ||
317 | delete: [54; 54), | ||
318 | insert: "T", | ||
319 | kind: TypeParam, | ||
320 | }, | ||
321 | CompletionItem { | ||
322 | label: "X<…>", | ||
323 | source_range: [54; 54), | ||
324 | delete: [54; 54), | ||
325 | insert: "X<$0>", | ||
326 | kind: Struct, | ||
327 | lookup: "X", | ||
328 | }, | ||
329 | ] | ||
330 | "### | ||
331 | ); | ||
332 | } | ||
333 | |||
334 | #[test] | ||
335 | fn completes_self_in_enum() { | ||
336 | assert_debug_snapshot!( | ||
337 | do_reference_completion( | ||
338 | r" | ||
339 | enum X { | ||
340 | Y(<|>) | ||
341 | } | ||
342 | " | ||
343 | ), | ||
344 | @r###" | ||
345 | [ | ||
346 | CompletionItem { | ||
347 | label: "Self", | ||
348 | source_range: [48; 48), | ||
349 | delete: [48; 48), | ||
350 | insert: "Self", | ||
351 | kind: TypeParam, | ||
352 | }, | ||
353 | CompletionItem { | ||
354 | label: "X", | ||
355 | source_range: [48; 48), | ||
356 | delete: [48; 48), | ||
357 | insert: "X", | ||
358 | kind: Enum, | ||
359 | }, | ||
360 | ] | ||
361 | "### | ||
362 | ); | ||
363 | } | ||
364 | |||
365 | #[test] | ||
366 | fn completes_module_items() { | ||
367 | assert_debug_snapshot!( | ||
368 | do_reference_completion( | ||
369 | r" | ||
370 | struct Foo; | ||
371 | enum Baz {} | ||
372 | fn quux() { | ||
373 | <|> | ||
374 | } | ||
375 | " | ||
376 | ), | ||
377 | @r###" | ||
378 | [ | ||
379 | CompletionItem { | ||
380 | label: "Baz", | ||
381 | source_range: [105; 105), | ||
382 | delete: [105; 105), | ||
383 | insert: "Baz", | ||
384 | kind: Enum, | ||
385 | }, | ||
386 | CompletionItem { | ||
387 | label: "Foo", | ||
388 | source_range: [105; 105), | ||
389 | delete: [105; 105), | ||
390 | insert: "Foo", | ||
391 | kind: Struct, | ||
392 | }, | ||
393 | CompletionItem { | ||
394 | label: "quux()", | ||
395 | source_range: [105; 105), | ||
396 | delete: [105; 105), | ||
397 | insert: "quux()$0", | ||
398 | kind: Function, | ||
399 | lookup: "quux", | ||
400 | detail: "fn quux()", | ||
401 | }, | ||
402 | ] | ||
403 | "### | ||
404 | ); | ||
405 | } | ||
406 | |||
407 | #[test] | ||
408 | fn completes_extern_prelude() { | ||
409 | assert_debug_snapshot!( | ||
410 | do_reference_completion( | ||
411 | r" | ||
412 | //- /lib.rs | ||
413 | use <|>; | ||
414 | |||
415 | //- /other_crate/lib.rs | ||
416 | // nothing here | ||
417 | " | ||
418 | ), | ||
419 | @r###" | ||
420 | [ | ||
421 | CompletionItem { | ||
422 | label: "other_crate", | ||
423 | source_range: [4; 4), | ||
424 | delete: [4; 4), | ||
425 | insert: "other_crate", | ||
426 | kind: Module, | ||
427 | }, | ||
428 | ] | ||
429 | "### | ||
430 | ); | ||
431 | } | ||
432 | |||
433 | #[test] | ||
434 | fn completes_module_items_in_nested_modules() { | ||
435 | assert_debug_snapshot!( | ||
436 | do_reference_completion( | ||
437 | r" | ||
438 | struct Foo; | ||
439 | mod m { | ||
440 | struct Bar; | ||
441 | fn quux() { <|> } | ||
442 | } | ||
443 | " | ||
444 | ), | ||
445 | @r###" | ||
446 | [ | ||
447 | CompletionItem { | ||
448 | label: "Bar", | ||
449 | source_range: [117; 117), | ||
450 | delete: [117; 117), | ||
451 | insert: "Bar", | ||
452 | kind: Struct, | ||
453 | }, | ||
454 | CompletionItem { | ||
455 | label: "quux()", | ||
456 | source_range: [117; 117), | ||
457 | delete: [117; 117), | ||
458 | insert: "quux()$0", | ||
459 | kind: Function, | ||
460 | lookup: "quux", | ||
461 | detail: "fn quux()", | ||
462 | }, | ||
463 | ] | ||
464 | "### | ||
465 | ); | ||
466 | } | ||
467 | |||
468 | #[test] | ||
469 | fn completes_return_type() { | ||
470 | assert_debug_snapshot!( | ||
471 | do_reference_completion( | ||
472 | r" | ||
473 | struct Foo; | ||
474 | fn x() -> <|> | ||
475 | " | ||
476 | ), | ||
477 | @r###" | ||
478 | [ | ||
479 | CompletionItem { | ||
480 | label: "Foo", | ||
481 | source_range: [55; 55), | ||
482 | delete: [55; 55), | ||
483 | insert: "Foo", | ||
484 | kind: Struct, | ||
485 | }, | ||
486 | CompletionItem { | ||
487 | label: "x()", | ||
488 | source_range: [55; 55), | ||
489 | delete: [55; 55), | ||
490 | insert: "x()$0", | ||
491 | kind: Function, | ||
492 | lookup: "x", | ||
493 | detail: "fn x()", | ||
494 | }, | ||
495 | ] | ||
496 | "### | ||
497 | ); | ||
498 | } | ||
499 | |||
500 | #[test] | ||
501 | fn dont_show_both_completions_for_shadowing() { | ||
502 | assert_debug_snapshot!( | ||
503 | do_reference_completion( | ||
504 | r" | ||
505 | fn foo() { | ||
506 | let bar = 92; | ||
507 | { | ||
508 | let bar = 62; | ||
509 | <|> | ||
510 | } | ||
511 | } | ||
512 | " | ||
513 | ), | ||
514 | @r###" | ||
515 | [ | ||
516 | CompletionItem { | ||
517 | label: "bar", | ||
518 | source_range: [146; 146), | ||
519 | delete: [146; 146), | ||
520 | insert: "bar", | ||
521 | kind: Binding, | ||
522 | detail: "i32", | ||
523 | }, | ||
524 | CompletionItem { | ||
525 | label: "foo()", | ||
526 | source_range: [146; 146), | ||
527 | delete: [146; 146), | ||
528 | insert: "foo()$0", | ||
529 | kind: Function, | ||
530 | lookup: "foo", | ||
531 | detail: "fn foo()", | ||
532 | }, | ||
533 | ] | ||
534 | "### | ||
535 | ); | ||
536 | } | ||
537 | |||
538 | #[test] | ||
539 | fn completes_self_in_methods() { | ||
540 | assert_debug_snapshot!( | ||
541 | do_reference_completion(r"impl S { fn foo(&self) { <|> } }"), | ||
542 | @r###" | ||
543 | [ | ||
544 | CompletionItem { | ||
545 | label: "Self", | ||
546 | source_range: [25; 25), | ||
547 | delete: [25; 25), | ||
548 | insert: "Self", | ||
549 | kind: TypeParam, | ||
550 | }, | ||
551 | CompletionItem { | ||
552 | label: "self", | ||
553 | source_range: [25; 25), | ||
554 | delete: [25; 25), | ||
555 | insert: "self", | ||
556 | kind: Binding, | ||
557 | detail: "&{unknown}", | ||
558 | }, | ||
559 | ] | ||
560 | "### | ||
561 | ); | ||
562 | } | ||
563 | |||
564 | #[test] | ||
565 | fn completes_prelude() { | ||
566 | assert_debug_snapshot!( | ||
567 | do_reference_completion( | ||
568 | " | ||
569 | //- /main.rs | ||
570 | fn foo() { let x: <|> } | ||
571 | |||
572 | //- /std/lib.rs | ||
573 | #[prelude_import] | ||
574 | use prelude::*; | ||
575 | |||
576 | mod prelude { | ||
577 | struct Option; | ||
578 | } | ||
579 | " | ||
580 | ), | ||
581 | @r###" | ||
582 | [ | ||
583 | CompletionItem { | ||
584 | label: "Option", | ||
585 | source_range: [18; 18), | ||
586 | delete: [18; 18), | ||
587 | insert: "Option", | ||
588 | kind: Struct, | ||
589 | }, | ||
590 | CompletionItem { | ||
591 | label: "foo()", | ||
592 | source_range: [18; 18), | ||
593 | delete: [18; 18), | ||
594 | insert: "foo()$0", | ||
595 | kind: Function, | ||
596 | lookup: "foo", | ||
597 | detail: "fn foo()", | ||
598 | }, | ||
599 | CompletionItem { | ||
600 | label: "std", | ||
601 | source_range: [18; 18), | ||
602 | delete: [18; 18), | ||
603 | insert: "std", | ||
604 | kind: Module, | ||
605 | }, | ||
606 | ] | ||
607 | "### | ||
608 | ); | ||
609 | } | ||
610 | |||
611 | #[test] | ||
612 | fn completes_std_prelude_if_core_is_defined() { | ||
613 | assert_debug_snapshot!( | ||
614 | do_reference_completion( | ||
615 | " | ||
616 | //- /main.rs | ||
617 | fn foo() { let x: <|> } | ||
618 | |||
619 | //- /core/lib.rs | ||
620 | #[prelude_import] | ||
621 | use prelude::*; | ||
622 | |||
623 | mod prelude { | ||
624 | struct Option; | ||
625 | } | ||
626 | |||
627 | //- /std/lib.rs | ||
628 | #[prelude_import] | ||
629 | use prelude::*; | ||
630 | |||
631 | mod prelude { | ||
632 | struct String; | ||
633 | } | ||
634 | " | ||
635 | ), | ||
636 | @r###" | ||
637 | [ | ||
638 | CompletionItem { | ||
639 | label: "String", | ||
640 | source_range: [18; 18), | ||
641 | delete: [18; 18), | ||
642 | insert: "String", | ||
643 | kind: Struct, | ||
644 | }, | ||
645 | CompletionItem { | ||
646 | label: "core", | ||
647 | source_range: [18; 18), | ||
648 | delete: [18; 18), | ||
649 | insert: "core", | ||
650 | kind: Module, | ||
651 | }, | ||
652 | CompletionItem { | ||
653 | label: "foo()", | ||
654 | source_range: [18; 18), | ||
655 | delete: [18; 18), | ||
656 | insert: "foo()$0", | ||
657 | kind: Function, | ||
658 | lookup: "foo", | ||
659 | detail: "fn foo()", | ||
660 | }, | ||
661 | CompletionItem { | ||
662 | label: "std", | ||
663 | source_range: [18; 18), | ||
664 | delete: [18; 18), | ||
665 | insert: "std", | ||
666 | kind: Module, | ||
667 | }, | ||
668 | ] | ||
669 | "### | ||
670 | ); | ||
671 | } | ||
672 | |||
673 | #[test] | ||
674 | fn completes_macros_as_value() { | ||
675 | assert_debug_snapshot!( | ||
676 | do_reference_completion( | ||
677 | " | ||
678 | //- /main.rs | ||
679 | macro_rules! foo { | ||
680 | () => {} | ||
681 | } | ||
682 | |||
683 | #[macro_use] | ||
684 | mod m1 { | ||
685 | macro_rules! bar { | ||
686 | () => {} | ||
687 | } | ||
688 | } | ||
689 | |||
690 | mod m2 { | ||
691 | macro_rules! nope { | ||
692 | () => {} | ||
693 | } | ||
694 | |||
695 | #[macro_export] | ||
696 | macro_rules! baz { | ||
697 | () => {} | ||
698 | } | ||
699 | } | ||
700 | |||
701 | fn main() { | ||
702 | let v = <|> | ||
703 | } | ||
704 | " | ||
705 | ), | ||
706 | @r###" | ||
707 | [ | ||
708 | CompletionItem { | ||
709 | label: "bar!", | ||
710 | source_range: [252; 252), | ||
711 | delete: [252; 252), | ||
712 | insert: "bar!($0)", | ||
713 | kind: Macro, | ||
714 | detail: "macro_rules! bar", | ||
715 | }, | ||
716 | CompletionItem { | ||
717 | label: "baz!", | ||
718 | source_range: [252; 252), | ||
719 | delete: [252; 252), | ||
720 | insert: "baz!($0)", | ||
721 | kind: Macro, | ||
722 | detail: "#[macro_export]\nmacro_rules! baz", | ||
723 | }, | ||
724 | CompletionItem { | ||
725 | label: "foo!", | ||
726 | source_range: [252; 252), | ||
727 | delete: [252; 252), | ||
728 | insert: "foo!($0)", | ||
729 | kind: Macro, | ||
730 | detail: "macro_rules! foo", | ||
731 | }, | ||
732 | CompletionItem { | ||
733 | label: "m1", | ||
734 | source_range: [252; 252), | ||
735 | delete: [252; 252), | ||
736 | insert: "m1", | ||
737 | kind: Module, | ||
738 | }, | ||
739 | CompletionItem { | ||
740 | label: "m2", | ||
741 | source_range: [252; 252), | ||
742 | delete: [252; 252), | ||
743 | insert: "m2", | ||
744 | kind: Module, | ||
745 | }, | ||
746 | CompletionItem { | ||
747 | label: "main()", | ||
748 | source_range: [252; 252), | ||
749 | delete: [252; 252), | ||
750 | insert: "main()$0", | ||
751 | kind: Function, | ||
752 | lookup: "main", | ||
753 | detail: "fn main()", | ||
754 | }, | ||
755 | ] | ||
756 | "### | ||
757 | ); | ||
758 | } | ||
759 | |||
760 | #[test] | ||
761 | fn completes_both_macro_and_value() { | ||
762 | assert_debug_snapshot!( | ||
763 | do_reference_completion( | ||
764 | " | ||
765 | //- /main.rs | ||
766 | macro_rules! foo { | ||
767 | () => {} | ||
768 | } | ||
769 | |||
770 | fn foo() { | ||
771 | <|> | ||
772 | } | ||
773 | " | ||
774 | ), | ||
775 | @r###" | ||
776 | [ | ||
777 | CompletionItem { | ||
778 | label: "foo!", | ||
779 | source_range: [49; 49), | ||
780 | delete: [49; 49), | ||
781 | insert: "foo!($0)", | ||
782 | kind: Macro, | ||
783 | detail: "macro_rules! foo", | ||
784 | }, | ||
785 | CompletionItem { | ||
786 | label: "foo()", | ||
787 | source_range: [49; 49), | ||
788 | delete: [49; 49), | ||
789 | insert: "foo()$0", | ||
790 | kind: Function, | ||
791 | lookup: "foo", | ||
792 | detail: "fn foo()", | ||
793 | }, | ||
794 | ] | ||
795 | "### | ||
796 | ); | ||
797 | } | ||
798 | |||
799 | #[test] | ||
800 | fn completes_macros_as_type() { | ||
801 | assert_debug_snapshot!( | ||
802 | do_reference_completion( | ||
803 | " | ||
804 | //- /main.rs | ||
805 | macro_rules! foo { | ||
806 | () => {} | ||
807 | } | ||
808 | |||
809 | fn main() { | ||
810 | let x: <|> | ||
811 | } | ||
812 | " | ||
813 | ), | ||
814 | @r###" | ||
815 | [ | ||
816 | CompletionItem { | ||
817 | label: "foo!", | ||
818 | source_range: [57; 57), | ||
819 | delete: [57; 57), | ||
820 | insert: "foo!($0)", | ||
821 | kind: Macro, | ||
822 | detail: "macro_rules! foo", | ||
823 | }, | ||
824 | CompletionItem { | ||
825 | label: "main()", | ||
826 | source_range: [57; 57), | ||
827 | delete: [57; 57), | ||
828 | insert: "main()$0", | ||
829 | kind: Function, | ||
830 | lookup: "main", | ||
831 | detail: "fn main()", | ||
832 | }, | ||
833 | ] | ||
834 | "### | ||
835 | ); | ||
836 | } | ||
837 | |||
838 | #[test] | ||
839 | fn completes_macros_as_stmt() { | ||
840 | assert_debug_snapshot!( | ||
841 | do_reference_completion( | ||
842 | " | ||
843 | //- /main.rs | ||
844 | macro_rules! foo { | ||
845 | () => {} | ||
846 | } | ||
847 | |||
848 | fn main() { | ||
849 | <|> | ||
850 | } | ||
851 | " | ||
852 | ), | ||
853 | @r###" | ||
854 | [ | ||
855 | CompletionItem { | ||
856 | label: "foo!", | ||
857 | source_range: [50; 50), | ||
858 | delete: [50; 50), | ||
859 | insert: "foo!($0)", | ||
860 | kind: Macro, | ||
861 | detail: "macro_rules! foo", | ||
862 | }, | ||
863 | CompletionItem { | ||
864 | label: "main()", | ||
865 | source_range: [50; 50), | ||
866 | delete: [50; 50), | ||
867 | insert: "main()$0", | ||
868 | kind: Function, | ||
869 | lookup: "main", | ||
870 | detail: "fn main()", | ||
871 | }, | ||
872 | ] | ||
873 | "### | ||
874 | ); | ||
875 | } | ||
876 | } | ||