diff options
Diffstat (limited to 'crates/ra_assists/src/utils/insert_use.rs')
-rw-r--r-- | crates/ra_assists/src/utils/insert_use.rs | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/crates/ra_assists/src/utils/insert_use.rs b/crates/ra_assists/src/utils/insert_use.rs index 0ee43482f..8c4f33e59 100644 --- a/crates/ra_assists/src/utils/insert_use.rs +++ b/crates/ra_assists/src/utils/insert_use.rs | |||
@@ -12,6 +12,20 @@ use ra_syntax::{ | |||
12 | use ra_text_edit::TextEditBuilder; | 12 | use ra_text_edit::TextEditBuilder; |
13 | 13 | ||
14 | use crate::assist_context::AssistContext; | 14 | use crate::assist_context::AssistContext; |
15 | use either::Either; | ||
16 | |||
17 | /// Determines the containing syntax node in which to insert a `use` statement affecting `position`. | ||
18 | pub(crate) fn find_insert_use_container( | ||
19 | position: &SyntaxNode, | ||
20 | ctx: &AssistContext, | ||
21 | ) -> Option<Either<ast::ItemList, ast::SourceFile>> { | ||
22 | ctx.sema.ancestors_with_macros(position.clone()).find_map(|n| { | ||
23 | if let Some(module) = ast::Module::cast(n.clone()) { | ||
24 | return module.item_list().map(|it| Either::Left(it)); | ||
25 | } | ||
26 | Some(Either::Right(ast::SourceFile::cast(n)?)) | ||
27 | }) | ||
28 | } | ||
15 | 29 | ||
16 | /// Creates and inserts a use statement for the given path to import. | 30 | /// Creates and inserts a use statement for the given path to import. |
17 | /// The use statement is inserted in the scope most appropriate to the | 31 | /// The use statement is inserted in the scope most appropriate to the |
@@ -24,15 +38,11 @@ pub(crate) fn insert_use_statement( | |||
24 | builder: &mut TextEditBuilder, | 38 | builder: &mut TextEditBuilder, |
25 | ) { | 39 | ) { |
26 | let target = path_to_import.to_string().split("::").map(SmolStr::new).collect::<Vec<_>>(); | 40 | let target = path_to_import.to_string().split("::").map(SmolStr::new).collect::<Vec<_>>(); |
27 | let container = ctx.sema.ancestors_with_macros(position.clone()).find_map(|n| { | 41 | let container = find_insert_use_container(position, ctx); |
28 | if let Some(module) = ast::Module::cast(n.clone()) { | ||
29 | return module.item_list().map(|it| it.syntax().clone()); | ||
30 | } | ||
31 | ast::SourceFile::cast(n).map(|it| it.syntax().clone()) | ||
32 | }); | ||
33 | 42 | ||
34 | if let Some(container) = container { | 43 | if let Some(container) = container { |
35 | let action = best_action_for_target(container, position.clone(), &target); | 44 | let syntax = container.either(|l| l.syntax().clone(), |r| r.syntax().clone()); |
45 | let action = best_action_for_target(syntax, position.clone(), &target); | ||
36 | make_assist(&action, &target, builder); | 46 | make_assist(&action, &target, builder); |
37 | } | 47 | } |
38 | } | 48 | } |