diff options
author | Chetan Khilosiya <[email protected]> | 2021-02-22 18:47:48 +0000 |
---|---|---|
committer | Chetan Khilosiya <[email protected]> | 2021-02-22 19:29:16 +0000 |
commit | e4756cb4f6e66097638b9d101589358976be2ba8 (patch) | |
tree | b6ca0ae6b45b57834476ae0f9985cec3a6bd9090 /crates/assists/src/handlers/auto_import.rs | |
parent | 8687053b118f47ce1a4962d0baa19b22d40d2758 (diff) |
7526: Rename crate assists to ide_assists.
Diffstat (limited to 'crates/assists/src/handlers/auto_import.rs')
-rw-r--r-- | crates/assists/src/handlers/auto_import.rs | 970 |
1 files changed, 0 insertions, 970 deletions
diff --git a/crates/assists/src/handlers/auto_import.rs b/crates/assists/src/handlers/auto_import.rs deleted file mode 100644 index e93901cb3..000000000 --- a/crates/assists/src/handlers/auto_import.rs +++ /dev/null | |||
@@ -1,970 +0,0 @@ | |||
1 | use ide_db::helpers::{ | ||
2 | import_assets::{ImportAssets, ImportCandidate}, | ||
3 | insert_use::{insert_use, ImportScope}, | ||
4 | mod_path_to_ast, | ||
5 | }; | ||
6 | use syntax::{ast, AstNode, SyntaxNode}; | ||
7 | |||
8 | use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel}; | ||
9 | |||
10 | // Feature: Auto Import | ||
11 | // | ||
12 | // Using the `auto-import` assist it is possible to insert missing imports for unresolved items. | ||
13 | // When inserting an import it will do so in a structured manner by keeping imports grouped, | ||
14 | // separated by a newline in the following order: | ||
15 | // | ||
16 | // - `std` and `core` | ||
17 | // - External Crates | ||
18 | // - Current Crate, paths prefixed by `crate` | ||
19 | // - Current Module, paths prefixed by `self` | ||
20 | // - Super Module, paths prefixed by `super` | ||
21 | // | ||
22 | // Example: | ||
23 | // ```rust | ||
24 | // use std::fs::File; | ||
25 | // | ||
26 | // use itertools::Itertools; | ||
27 | // use syntax::ast; | ||
28 | // | ||
29 | // use crate::utils::insert_use; | ||
30 | // | ||
31 | // use self::auto_import; | ||
32 | // | ||
33 | // use super::AssistContext; | ||
34 | // ``` | ||
35 | // | ||
36 | // .Merge Behaviour | ||
37 | // | ||
38 | // It is possible to configure how use-trees are merged with the `importMergeBehaviour` setting. | ||
39 | // It has the following configurations: | ||
40 | // | ||
41 | // - `full`: This setting will cause auto-import to always completely merge use-trees that share the | ||
42 | // same path prefix while also merging inner trees that share the same path-prefix. This kind of | ||
43 | // nesting is only supported in Rust versions later than 1.24. | ||
44 | // - `last`: This setting will cause auto-import to merge use-trees as long as the resulting tree | ||
45 | // will only contain a nesting of single segment paths at the very end. | ||
46 | // - `none`: This setting will cause auto-import to never merge use-trees keeping them as simple | ||
47 | // paths. | ||
48 | // | ||
49 | // In `VS Code` the configuration for this is `rust-analyzer.assist.importMergeBehaviour`. | ||
50 | // | ||
51 | // .Import Prefix | ||
52 | // | ||
53 | // The style of imports in the same crate is configurable through the `importPrefix` setting. | ||
54 | // It has the following configurations: | ||
55 | // | ||
56 | // - `by_crate`: This setting will force paths to be always absolute, starting with the `crate` | ||
57 | // prefix, unless the item is defined outside of the current crate. | ||
58 | // - `by_self`: This setting will force paths that are relative to the current module to always | ||
59 | // start with `self`. This will result in paths that always start with either `crate`, `self`, | ||
60 | // `super` or an extern crate identifier. | ||
61 | // - `plain`: This setting does not impose any restrictions in imports. | ||
62 | // | ||
63 | // In `VS Code` the configuration for this is `rust-analyzer.assist.importPrefix`. | ||
64 | |||
65 | // Assist: auto_import | ||
66 | // | ||
67 | // If the name is unresolved, provides all possible imports for it. | ||
68 | // | ||
69 | // ``` | ||
70 | // fn main() { | ||
71 | // let map = HashMap$0::new(); | ||
72 | // } | ||
73 | // # pub mod std { pub mod collections { pub struct HashMap { } } } | ||
74 | // ``` | ||
75 | // -> | ||
76 | // ``` | ||
77 | // use std::collections::HashMap; | ||
78 | // | ||
79 | // fn main() { | ||
80 | // let map = HashMap::new(); | ||
81 | // } | ||
82 | // # pub mod std { pub mod collections { pub struct HashMap { } } } | ||
83 | // ``` | ||
84 | pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
85 | let (import_assets, syntax_under_caret) = find_importable_node(ctx)?; | ||
86 | let proposed_imports = | ||
87 | import_assets.search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind); | ||
88 | if proposed_imports.is_empty() { | ||
89 | return None; | ||
90 | } | ||
91 | |||
92 | let range = ctx.sema.original_range(&syntax_under_caret).range; | ||
93 | let group = import_group_message(import_assets.import_candidate()); | ||
94 | let scope = ImportScope::find_insert_use_container(&syntax_under_caret, &ctx.sema)?; | ||
95 | for (import, _) in proposed_imports { | ||
96 | acc.add_group( | ||
97 | &group, | ||
98 | AssistId("auto_import", AssistKind::QuickFix), | ||
99 | format!("Import `{}`", &import), | ||
100 | range, | ||
101 | |builder| { | ||
102 | let rewriter = | ||
103 | insert_use(&scope, mod_path_to_ast(&import), ctx.config.insert_use.merge); | ||
104 | builder.rewrite(rewriter); | ||
105 | }, | ||
106 | ); | ||
107 | } | ||
108 | Some(()) | ||
109 | } | ||
110 | |||
111 | pub(super) fn find_importable_node(ctx: &AssistContext) -> Option<(ImportAssets, SyntaxNode)> { | ||
112 | if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::<ast::Path>() { | ||
113 | ImportAssets::for_exact_path(&path_under_caret, &ctx.sema) | ||
114 | .zip(Some(path_under_caret.syntax().clone())) | ||
115 | } else if let Some(method_under_caret) = | ||
116 | ctx.find_node_at_offset_with_descend::<ast::MethodCallExpr>() | ||
117 | { | ||
118 | ImportAssets::for_method_call(&method_under_caret, &ctx.sema) | ||
119 | .zip(Some(method_under_caret.syntax().clone())) | ||
120 | } else { | ||
121 | None | ||
122 | } | ||
123 | } | ||
124 | |||
125 | fn import_group_message(import_candidate: &ImportCandidate) -> GroupLabel { | ||
126 | let name = match import_candidate { | ||
127 | ImportCandidate::Path(candidate) => format!("Import {}", candidate.name.text()), | ||
128 | ImportCandidate::TraitAssocItem(candidate) => { | ||
129 | format!("Import a trait for item {}", candidate.name.text()) | ||
130 | } | ||
131 | ImportCandidate::TraitMethod(candidate) => { | ||
132 | format!("Import a trait for method {}", candidate.name.text()) | ||
133 | } | ||
134 | }; | ||
135 | GroupLabel(name) | ||
136 | } | ||
137 | |||
138 | #[cfg(test)] | ||
139 | mod tests { | ||
140 | use super::*; | ||
141 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; | ||
142 | |||
143 | #[test] | ||
144 | fn applicable_when_found_an_import_partial() { | ||
145 | check_assist( | ||
146 | auto_import, | ||
147 | r" | ||
148 | mod std { | ||
149 | pub mod fmt { | ||
150 | pub struct Formatter; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | use std::fmt; | ||
155 | |||
156 | $0Formatter | ||
157 | ", | ||
158 | r" | ||
159 | mod std { | ||
160 | pub mod fmt { | ||
161 | pub struct Formatter; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | use std::fmt::{self, Formatter}; | ||
166 | |||
167 | Formatter | ||
168 | ", | ||
169 | ); | ||
170 | } | ||
171 | |||
172 | #[test] | ||
173 | fn applicable_when_found_an_import() { | ||
174 | check_assist( | ||
175 | auto_import, | ||
176 | r" | ||
177 | $0PubStruct | ||
178 | |||
179 | pub mod PubMod { | ||
180 | pub struct PubStruct; | ||
181 | } | ||
182 | ", | ||
183 | r" | ||
184 | use PubMod::PubStruct; | ||
185 | |||
186 | PubStruct | ||
187 | |||
188 | pub mod PubMod { | ||
189 | pub struct PubStruct; | ||
190 | } | ||
191 | ", | ||
192 | ); | ||
193 | } | ||
194 | |||
195 | #[test] | ||
196 | fn applicable_when_found_an_import_in_macros() { | ||
197 | check_assist( | ||
198 | auto_import, | ||
199 | r" | ||
200 | macro_rules! foo { | ||
201 | ($i:ident) => { fn foo(a: $i) {} } | ||
202 | } | ||
203 | foo!(Pub$0Struct); | ||
204 | |||
205 | pub mod PubMod { | ||
206 | pub struct PubStruct; | ||
207 | } | ||
208 | ", | ||
209 | r" | ||
210 | use PubMod::PubStruct; | ||
211 | |||
212 | macro_rules! foo { | ||
213 | ($i:ident) => { fn foo(a: $i) {} } | ||
214 | } | ||
215 | foo!(PubStruct); | ||
216 | |||
217 | pub mod PubMod { | ||
218 | pub struct PubStruct; | ||
219 | } | ||
220 | ", | ||
221 | ); | ||
222 | } | ||
223 | |||
224 | #[test] | ||
225 | fn auto_imports_are_merged() { | ||
226 | check_assist( | ||
227 | auto_import, | ||
228 | r" | ||
229 | use PubMod::PubStruct1; | ||
230 | |||
231 | struct Test { | ||
232 | test: Pub$0Struct2<u8>, | ||
233 | } | ||
234 | |||
235 | pub mod PubMod { | ||
236 | pub struct PubStruct1; | ||
237 | pub struct PubStruct2<T> { | ||
238 | _t: T, | ||
239 | } | ||
240 | } | ||
241 | ", | ||
242 | r" | ||
243 | use PubMod::{PubStruct1, PubStruct2}; | ||
244 | |||
245 | struct Test { | ||
246 | test: PubStruct2<u8>, | ||
247 | } | ||
248 | |||
249 | pub mod PubMod { | ||
250 | pub struct PubStruct1; | ||
251 | pub struct PubStruct2<T> { | ||
252 | _t: T, | ||
253 | } | ||
254 | } | ||
255 | ", | ||
256 | ); | ||
257 | } | ||
258 | |||
259 | #[test] | ||
260 | fn applicable_when_found_multiple_imports() { | ||
261 | check_assist( | ||
262 | auto_import, | ||
263 | r" | ||
264 | PubSt$0ruct | ||
265 | |||
266 | pub mod PubMod1 { | ||
267 | pub struct PubStruct; | ||
268 | } | ||
269 | pub mod PubMod2 { | ||
270 | pub struct PubStruct; | ||
271 | } | ||
272 | pub mod PubMod3 { | ||
273 | pub struct PubStruct; | ||
274 | } | ||
275 | ", | ||
276 | r" | ||
277 | use PubMod3::PubStruct; | ||
278 | |||
279 | PubStruct | ||
280 | |||
281 | pub mod PubMod1 { | ||
282 | pub struct PubStruct; | ||
283 | } | ||
284 | pub mod PubMod2 { | ||
285 | pub struct PubStruct; | ||
286 | } | ||
287 | pub mod PubMod3 { | ||
288 | pub struct PubStruct; | ||
289 | } | ||
290 | ", | ||
291 | ); | ||
292 | } | ||
293 | |||
294 | #[test] | ||
295 | fn not_applicable_for_already_imported_types() { | ||
296 | check_assist_not_applicable( | ||
297 | auto_import, | ||
298 | r" | ||
299 | use PubMod::PubStruct; | ||
300 | |||
301 | PubStruct$0 | ||
302 | |||
303 | pub mod PubMod { | ||
304 | pub struct PubStruct; | ||
305 | } | ||
306 | ", | ||
307 | ); | ||
308 | } | ||
309 | |||
310 | #[test] | ||
311 | fn not_applicable_for_types_with_private_paths() { | ||
312 | check_assist_not_applicable( | ||
313 | auto_import, | ||
314 | r" | ||
315 | PrivateStruct$0 | ||
316 | |||
317 | pub mod PubMod { | ||
318 | struct PrivateStruct; | ||
319 | } | ||
320 | ", | ||
321 | ); | ||
322 | } | ||
323 | |||
324 | #[test] | ||
325 | fn not_applicable_when_no_imports_found() { | ||
326 | check_assist_not_applicable( | ||
327 | auto_import, | ||
328 | " | ||
329 | PubStruct$0", | ||
330 | ); | ||
331 | } | ||
332 | |||
333 | #[test] | ||
334 | fn not_applicable_in_import_statements() { | ||
335 | check_assist_not_applicable( | ||
336 | auto_import, | ||
337 | r" | ||
338 | use PubStruct$0; | ||
339 | |||
340 | pub mod PubMod { | ||
341 | pub struct PubStruct; | ||
342 | }", | ||
343 | ); | ||
344 | } | ||
345 | |||
346 | #[test] | ||
347 | fn function_import() { | ||
348 | check_assist( | ||
349 | auto_import, | ||
350 | r" | ||
351 | test_function$0 | ||
352 | |||
353 | pub mod PubMod { | ||
354 | pub fn test_function() {}; | ||
355 | } | ||
356 | ", | ||
357 | r" | ||
358 | use PubMod::test_function; | ||
359 | |||
360 | test_function | ||
361 | |||
362 | pub mod PubMod { | ||
363 | pub fn test_function() {}; | ||
364 | } | ||
365 | ", | ||
366 | ); | ||
367 | } | ||
368 | |||
369 | #[test] | ||
370 | fn macro_import() { | ||
371 | check_assist( | ||
372 | auto_import, | ||
373 | r" | ||
374 | //- /lib.rs crate:crate_with_macro | ||
375 | #[macro_export] | ||
376 | macro_rules! foo { | ||
377 | () => () | ||
378 | } | ||
379 | |||
380 | //- /main.rs crate:main deps:crate_with_macro | ||
381 | fn main() { | ||
382 | foo$0 | ||
383 | } | ||
384 | ", | ||
385 | r"use crate_with_macro::foo; | ||
386 | |||
387 | fn main() { | ||
388 | foo | ||
389 | } | ||
390 | ", | ||
391 | ); | ||
392 | } | ||
393 | |||
394 | #[test] | ||
395 | fn auto_import_target() { | ||
396 | check_assist_target( | ||
397 | auto_import, | ||
398 | r" | ||
399 | struct AssistInfo { | ||
400 | group_label: Option<$0GroupLabel>, | ||
401 | } | ||
402 | |||
403 | mod m { pub struct GroupLabel; } | ||
404 | ", | ||
405 | "GroupLabel", | ||
406 | ) | ||
407 | } | ||
408 | |||
409 | #[test] | ||
410 | fn not_applicable_when_path_start_is_imported() { | ||
411 | check_assist_not_applicable( | ||
412 | auto_import, | ||
413 | r" | ||
414 | pub mod mod1 { | ||
415 | pub mod mod2 { | ||
416 | pub mod mod3 { | ||
417 | pub struct TestStruct; | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | |||
422 | use mod1::mod2; | ||
423 | fn main() { | ||
424 | mod2::mod3::TestStruct$0 | ||
425 | } | ||
426 | ", | ||
427 | ); | ||
428 | } | ||
429 | |||
430 | #[test] | ||
431 | fn not_applicable_for_imported_function() { | ||
432 | check_assist_not_applicable( | ||
433 | auto_import, | ||
434 | r" | ||
435 | pub mod test_mod { | ||
436 | pub fn test_function() {} | ||
437 | } | ||
438 | |||
439 | use test_mod::test_function; | ||
440 | fn main() { | ||
441 | test_function$0 | ||
442 | } | ||
443 | ", | ||
444 | ); | ||
445 | } | ||
446 | |||
447 | #[test] | ||
448 | fn associated_struct_function() { | ||
449 | check_assist( | ||
450 | auto_import, | ||
451 | r" | ||
452 | mod test_mod { | ||
453 | pub struct TestStruct {} | ||
454 | impl TestStruct { | ||
455 | pub fn test_function() {} | ||
456 | } | ||
457 | } | ||
458 | |||
459 | fn main() { | ||
460 | TestStruct::test_function$0 | ||
461 | } | ||
462 | ", | ||
463 | r" | ||
464 | use test_mod::TestStruct; | ||
465 | |||
466 | mod test_mod { | ||
467 | pub struct TestStruct {} | ||
468 | impl TestStruct { | ||
469 | pub fn test_function() {} | ||
470 | } | ||
471 | } | ||
472 | |||
473 | fn main() { | ||
474 | TestStruct::test_function | ||
475 | } | ||
476 | ", | ||
477 | ); | ||
478 | } | ||
479 | |||
480 | #[test] | ||
481 | fn associated_struct_const() { | ||
482 | check_assist( | ||
483 | auto_import, | ||
484 | r" | ||
485 | mod test_mod { | ||
486 | pub struct TestStruct {} | ||
487 | impl TestStruct { | ||
488 | const TEST_CONST: u8 = 42; | ||
489 | } | ||
490 | } | ||
491 | |||
492 | fn main() { | ||
493 | TestStruct::TEST_CONST$0 | ||
494 | } | ||
495 | ", | ||
496 | r" | ||
497 | use test_mod::TestStruct; | ||
498 | |||
499 | mod test_mod { | ||
500 | pub struct TestStruct {} | ||
501 | impl TestStruct { | ||
502 | const TEST_CONST: u8 = 42; | ||
503 | } | ||
504 | } | ||
505 | |||
506 | fn main() { | ||
507 | TestStruct::TEST_CONST | ||
508 | } | ||
509 | ", | ||
510 | ); | ||
511 | } | ||
512 | |||
513 | #[test] | ||
514 | fn associated_trait_function() { | ||
515 | check_assist( | ||
516 | auto_import, | ||
517 | r" | ||
518 | mod test_mod { | ||
519 | pub trait TestTrait { | ||
520 | fn test_function(); | ||
521 | } | ||
522 | pub struct TestStruct {} | ||
523 | impl TestTrait for TestStruct { | ||
524 | fn test_function() {} | ||
525 | } | ||
526 | } | ||
527 | |||
528 | fn main() { | ||
529 | test_mod::TestStruct::test_function$0 | ||
530 | } | ||
531 | ", | ||
532 | r" | ||
533 | use test_mod::TestTrait; | ||
534 | |||
535 | mod test_mod { | ||
536 | pub trait TestTrait { | ||
537 | fn test_function(); | ||
538 | } | ||
539 | pub struct TestStruct {} | ||
540 | impl TestTrait for TestStruct { | ||
541 | fn test_function() {} | ||
542 | } | ||
543 | } | ||
544 | |||
545 | fn main() { | ||
546 | test_mod::TestStruct::test_function | ||
547 | } | ||
548 | ", | ||
549 | ); | ||
550 | } | ||
551 | |||
552 | #[test] | ||
553 | fn not_applicable_for_imported_trait_for_function() { | ||
554 | check_assist_not_applicable( | ||
555 | auto_import, | ||
556 | r" | ||
557 | mod test_mod { | ||
558 | pub trait TestTrait { | ||
559 | fn test_function(); | ||
560 | } | ||
561 | pub trait TestTrait2 { | ||
562 | fn test_function(); | ||
563 | } | ||
564 | pub enum TestEnum { | ||
565 | One, | ||
566 | Two, | ||
567 | } | ||
568 | impl TestTrait2 for TestEnum { | ||
569 | fn test_function() {} | ||
570 | } | ||
571 | impl TestTrait for TestEnum { | ||
572 | fn test_function() {} | ||
573 | } | ||
574 | } | ||
575 | |||
576 | use test_mod::TestTrait2; | ||
577 | fn main() { | ||
578 | test_mod::TestEnum::test_function$0; | ||
579 | } | ||
580 | ", | ||
581 | ) | ||
582 | } | ||
583 | |||
584 | #[test] | ||
585 | fn associated_trait_const() { | ||
586 | check_assist( | ||
587 | auto_import, | ||
588 | r" | ||
589 | mod test_mod { | ||
590 | pub trait TestTrait { | ||
591 | const TEST_CONST: u8; | ||
592 | } | ||
593 | pub struct TestStruct {} | ||
594 | impl TestTrait for TestStruct { | ||
595 | const TEST_CONST: u8 = 42; | ||
596 | } | ||
597 | } | ||
598 | |||
599 | fn main() { | ||
600 | test_mod::TestStruct::TEST_CONST$0 | ||
601 | } | ||
602 | ", | ||
603 | r" | ||
604 | use test_mod::TestTrait; | ||
605 | |||
606 | mod test_mod { | ||
607 | pub trait TestTrait { | ||
608 | const TEST_CONST: u8; | ||
609 | } | ||
610 | pub struct TestStruct {} | ||
611 | impl TestTrait for TestStruct { | ||
612 | const TEST_CONST: u8 = 42; | ||
613 | } | ||
614 | } | ||
615 | |||
616 | fn main() { | ||
617 | test_mod::TestStruct::TEST_CONST | ||
618 | } | ||
619 | ", | ||
620 | ); | ||
621 | } | ||
622 | |||
623 | #[test] | ||
624 | fn not_applicable_for_imported_trait_for_const() { | ||
625 | check_assist_not_applicable( | ||
626 | auto_import, | ||
627 | r" | ||
628 | mod test_mod { | ||
629 | pub trait TestTrait { | ||
630 | const TEST_CONST: u8; | ||
631 | } | ||
632 | pub trait TestTrait2 { | ||
633 | const TEST_CONST: f64; | ||
634 | } | ||
635 | pub enum TestEnum { | ||
636 | One, | ||
637 | Two, | ||
638 | } | ||
639 | impl TestTrait2 for TestEnum { | ||
640 | const TEST_CONST: f64 = 42.0; | ||
641 | } | ||
642 | impl TestTrait for TestEnum { | ||
643 | const TEST_CONST: u8 = 42; | ||
644 | } | ||
645 | } | ||
646 | |||
647 | use test_mod::TestTrait2; | ||
648 | fn main() { | ||
649 | test_mod::TestEnum::TEST_CONST$0; | ||
650 | } | ||
651 | ", | ||
652 | ) | ||
653 | } | ||
654 | |||
655 | #[test] | ||
656 | fn trait_method() { | ||
657 | check_assist( | ||
658 | auto_import, | ||
659 | r" | ||
660 | mod test_mod { | ||
661 | pub trait TestTrait { | ||
662 | fn test_method(&self); | ||
663 | } | ||
664 | pub struct TestStruct {} | ||
665 | impl TestTrait for TestStruct { | ||
666 | fn test_method(&self) {} | ||
667 | } | ||
668 | } | ||
669 | |||
670 | fn main() { | ||
671 | let test_struct = test_mod::TestStruct {}; | ||
672 | test_struct.test_meth$0od() | ||
673 | } | ||
674 | ", | ||
675 | r" | ||
676 | use test_mod::TestTrait; | ||
677 | |||
678 | mod test_mod { | ||
679 | pub trait TestTrait { | ||
680 | fn test_method(&self); | ||
681 | } | ||
682 | pub struct TestStruct {} | ||
683 | impl TestTrait for TestStruct { | ||
684 | fn test_method(&self) {} | ||
685 | } | ||
686 | } | ||
687 | |||
688 | fn main() { | ||
689 | let test_struct = test_mod::TestStruct {}; | ||
690 | test_struct.test_method() | ||
691 | } | ||
692 | ", | ||
693 | ); | ||
694 | } | ||
695 | |||
696 | #[test] | ||
697 | fn trait_method_cross_crate() { | ||
698 | check_assist( | ||
699 | auto_import, | ||
700 | r" | ||
701 | //- /main.rs crate:main deps:dep | ||
702 | fn main() { | ||
703 | let test_struct = dep::test_mod::TestStruct {}; | ||
704 | test_struct.test_meth$0od() | ||
705 | } | ||
706 | //- /dep.rs crate:dep | ||
707 | pub mod test_mod { | ||
708 | pub trait TestTrait { | ||
709 | fn test_method(&self); | ||
710 | } | ||
711 | pub struct TestStruct {} | ||
712 | impl TestTrait for TestStruct { | ||
713 | fn test_method(&self) {} | ||
714 | } | ||
715 | } | ||
716 | ", | ||
717 | r" | ||
718 | use dep::test_mod::TestTrait; | ||
719 | |||
720 | fn main() { | ||
721 | let test_struct = dep::test_mod::TestStruct {}; | ||
722 | test_struct.test_method() | ||
723 | } | ||
724 | ", | ||
725 | ); | ||
726 | } | ||
727 | |||
728 | #[test] | ||
729 | fn assoc_fn_cross_crate() { | ||
730 | check_assist( | ||
731 | auto_import, | ||
732 | r" | ||
733 | //- /main.rs crate:main deps:dep | ||
734 | fn main() { | ||
735 | dep::test_mod::TestStruct::test_func$0tion | ||
736 | } | ||
737 | //- /dep.rs crate:dep | ||
738 | pub mod test_mod { | ||
739 | pub trait TestTrait { | ||
740 | fn test_function(); | ||
741 | } | ||
742 | pub struct TestStruct {} | ||
743 | impl TestTrait for TestStruct { | ||
744 | fn test_function() {} | ||
745 | } | ||
746 | } | ||
747 | ", | ||
748 | r" | ||
749 | use dep::test_mod::TestTrait; | ||
750 | |||
751 | fn main() { | ||
752 | dep::test_mod::TestStruct::test_function | ||
753 | } | ||
754 | ", | ||
755 | ); | ||
756 | } | ||
757 | |||
758 | #[test] | ||
759 | fn assoc_const_cross_crate() { | ||
760 | check_assist( | ||
761 | auto_import, | ||
762 | r" | ||
763 | //- /main.rs crate:main deps:dep | ||
764 | fn main() { | ||
765 | dep::test_mod::TestStruct::CONST$0 | ||
766 | } | ||
767 | //- /dep.rs crate:dep | ||
768 | pub mod test_mod { | ||
769 | pub trait TestTrait { | ||
770 | const CONST: bool; | ||
771 | } | ||
772 | pub struct TestStruct {} | ||
773 | impl TestTrait for TestStruct { | ||
774 | const CONST: bool = true; | ||
775 | } | ||
776 | } | ||
777 | ", | ||
778 | r" | ||
779 | use dep::test_mod::TestTrait; | ||
780 | |||
781 | fn main() { | ||
782 | dep::test_mod::TestStruct::CONST | ||
783 | } | ||
784 | ", | ||
785 | ); | ||
786 | } | ||
787 | |||
788 | #[test] | ||
789 | fn assoc_fn_as_method_cross_crate() { | ||
790 | check_assist_not_applicable( | ||
791 | auto_import, | ||
792 | r" | ||
793 | //- /main.rs crate:main deps:dep | ||
794 | fn main() { | ||
795 | let test_struct = dep::test_mod::TestStruct {}; | ||
796 | test_struct.test_func$0tion() | ||
797 | } | ||
798 | //- /dep.rs crate:dep | ||
799 | pub mod test_mod { | ||
800 | pub trait TestTrait { | ||
801 | fn test_function(); | ||
802 | } | ||
803 | pub struct TestStruct {} | ||
804 | impl TestTrait for TestStruct { | ||
805 | fn test_function() {} | ||
806 | } | ||
807 | } | ||
808 | ", | ||
809 | ); | ||
810 | } | ||
811 | |||
812 | #[test] | ||
813 | fn private_trait_cross_crate() { | ||
814 | check_assist_not_applicable( | ||
815 | auto_import, | ||
816 | r" | ||
817 | //- /main.rs crate:main deps:dep | ||
818 | fn main() { | ||
819 | let test_struct = dep::test_mod::TestStruct {}; | ||
820 | test_struct.test_meth$0od() | ||
821 | } | ||
822 | //- /dep.rs crate:dep | ||
823 | pub mod test_mod { | ||
824 | trait TestTrait { | ||
825 | fn test_method(&self); | ||
826 | } | ||
827 | pub struct TestStruct {} | ||
828 | impl TestTrait for TestStruct { | ||
829 | fn test_method(&self) {} | ||
830 | } | ||
831 | } | ||
832 | ", | ||
833 | ); | ||
834 | } | ||
835 | |||
836 | #[test] | ||
837 | fn not_applicable_for_imported_trait_for_method() { | ||
838 | check_assist_not_applicable( | ||
839 | auto_import, | ||
840 | r" | ||
841 | mod test_mod { | ||
842 | pub trait TestTrait { | ||
843 | fn test_method(&self); | ||
844 | } | ||
845 | pub trait TestTrait2 { | ||
846 | fn test_method(&self); | ||
847 | } | ||
848 | pub enum TestEnum { | ||
849 | One, | ||
850 | Two, | ||
851 | } | ||
852 | impl TestTrait2 for TestEnum { | ||
853 | fn test_method(&self) {} | ||
854 | } | ||
855 | impl TestTrait for TestEnum { | ||
856 | fn test_method(&self) {} | ||
857 | } | ||
858 | } | ||
859 | |||
860 | use test_mod::TestTrait2; | ||
861 | fn main() { | ||
862 | let one = test_mod::TestEnum::One; | ||
863 | one.test$0_method(); | ||
864 | } | ||
865 | ", | ||
866 | ) | ||
867 | } | ||
868 | |||
869 | #[test] | ||
870 | fn dep_import() { | ||
871 | check_assist( | ||
872 | auto_import, | ||
873 | r" | ||
874 | //- /lib.rs crate:dep | ||
875 | pub struct Struct; | ||
876 | |||
877 | //- /main.rs crate:main deps:dep | ||
878 | fn main() { | ||
879 | Struct$0 | ||
880 | } | ||
881 | ", | ||
882 | r"use dep::Struct; | ||
883 | |||
884 | fn main() { | ||
885 | Struct | ||
886 | } | ||
887 | ", | ||
888 | ); | ||
889 | } | ||
890 | |||
891 | #[test] | ||
892 | fn whole_segment() { | ||
893 | // Tests that only imports whose last segment matches the identifier get suggested. | ||
894 | check_assist( | ||
895 | auto_import, | ||
896 | r" | ||
897 | //- /lib.rs crate:dep | ||
898 | pub mod fmt { | ||
899 | pub trait Display {} | ||
900 | } | ||
901 | |||
902 | pub fn panic_fmt() {} | ||
903 | |||
904 | //- /main.rs crate:main deps:dep | ||
905 | struct S; | ||
906 | |||
907 | impl f$0mt::Display for S {} | ||
908 | ", | ||
909 | r"use dep::fmt; | ||
910 | |||
911 | struct S; | ||
912 | |||
913 | impl fmt::Display for S {} | ||
914 | ", | ||
915 | ); | ||
916 | } | ||
917 | |||
918 | #[test] | ||
919 | fn macro_generated() { | ||
920 | // Tests that macro-generated items are suggested from external crates. | ||
921 | check_assist( | ||
922 | auto_import, | ||
923 | r" | ||
924 | //- /lib.rs crate:dep | ||
925 | macro_rules! mac { | ||
926 | () => { | ||
927 | pub struct Cheese; | ||
928 | }; | ||
929 | } | ||
930 | |||
931 | mac!(); | ||
932 | |||
933 | //- /main.rs crate:main deps:dep | ||
934 | fn main() { | ||
935 | Cheese$0; | ||
936 | } | ||
937 | ", | ||
938 | r"use dep::Cheese; | ||
939 | |||
940 | fn main() { | ||
941 | Cheese; | ||
942 | } | ||
943 | ", | ||
944 | ); | ||
945 | } | ||
946 | |||
947 | #[test] | ||
948 | fn casing() { | ||
949 | // Tests that differently cased names don't interfere and we only suggest the matching one. | ||
950 | check_assist( | ||
951 | auto_import, | ||
952 | r" | ||
953 | //- /lib.rs crate:dep | ||
954 | pub struct FMT; | ||
955 | pub struct fmt; | ||
956 | |||
957 | //- /main.rs crate:main deps:dep | ||
958 | fn main() { | ||
959 | FMT$0; | ||
960 | } | ||
961 | ", | ||
962 | r"use dep::FMT; | ||
963 | |||
964 | fn main() { | ||
965 | FMT; | ||
966 | } | ||
967 | ", | ||
968 | ); | ||
969 | } | ||
970 | } | ||