@@ -12,6 +12,20 @@ use ra_syntax::{
1212use ra_text_edit:: TextEditBuilder ;
1313
1414use 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+ }
1529
1630/// Creates and inserts a use statement for the given path to import.
1731/// The use statement is inserted in the scope most appropriate to the
@@ -24,15 +38,11 @@ pub(crate) fn insert_use_statement(
2438 builder : & mut TextEditBuilder ,
2539) {
2640 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| {
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- } ) ;
41+ let container = find_insert_use_container ( position, ctx) ;
3342
3443 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) ;
3646 make_assist ( & action, & target, builder) ;
3747 }
3848}
0 commit comments