1
- use std:: iter:: successors;
2
-
3
1
use syntax:: {
4
- algo:: { neighbor, skip_trivia_token, SyntaxRewriter } ,
5
- ast:: { self , edit:: AstNodeEdit , make} ,
6
- AstNode , Direction , InsertPosition , SyntaxElement , T ,
2
+ algo:: { neighbor, SyntaxRewriter } ,
3
+ ast, AstNode ,
7
4
} ;
8
5
9
6
use crate :: {
10
7
assist_context:: { AssistContext , Assists } ,
11
- utils:: next_prev,
8
+ utils:: {
9
+ insert_use:: { try_merge_imports, try_merge_trees} ,
10
+ next_prev, MergeBehaviour ,
11
+ } ,
12
12
AssistId , AssistKind ,
13
13
} ;
14
14
@@ -30,23 +30,22 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext) -> Option<()
30
30
let mut offset = ctx. offset ( ) ;
31
31
32
32
if let Some ( use_item) = tree. syntax ( ) . parent ( ) . and_then ( ast:: Use :: cast) {
33
- let ( merged, to_delete) = next_prev ( )
34
- . filter_map ( |dir| neighbor ( & use_item, dir) )
35
- . filter_map ( |it| Some ( ( it. clone ( ) , it. use_tree ( ) ?) ) )
36
- . find_map ( |( use_item, use_tree) | {
37
- Some ( ( try_merge_trees ( & tree, & use_tree) ?, use_item) )
33
+ let ( merged, to_delete) =
34
+ next_prev ( ) . filter_map ( |dir| neighbor ( & use_item, dir) ) . find_map ( |use_item2| {
35
+ try_merge_imports ( & use_item, & use_item2, MergeBehaviour :: Full ) . zip ( Some ( use_item2) )
38
36
} ) ?;
39
37
40
- rewriter. replace_ast ( & tree , & merged) ;
38
+ rewriter. replace_ast ( & use_item , & merged) ;
41
39
rewriter += to_delete. remove ( ) ;
42
40
43
41
if to_delete. syntax ( ) . text_range ( ) . end ( ) < offset {
44
42
offset -= to_delete. syntax ( ) . text_range ( ) . len ( ) ;
45
43
}
46
44
} else {
47
- let ( merged, to_delete) = next_prev ( )
48
- . filter_map ( |dir| neighbor ( & tree, dir) )
49
- . find_map ( |use_tree| Some ( ( try_merge_trees ( & tree, & use_tree) ?, use_tree. clone ( ) ) ) ) ?;
45
+ let ( merged, to_delete) =
46
+ next_prev ( ) . filter_map ( |dir| neighbor ( & tree, dir) ) . find_map ( |use_tree| {
47
+ try_merge_trees ( & tree, & use_tree, MergeBehaviour :: Full ) . zip ( Some ( use_tree) )
48
+ } ) ?;
50
49
51
50
rewriter. replace_ast ( & tree, & merged) ;
52
51
rewriter += to_delete. remove ( ) ;
@@ -67,66 +66,6 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext) -> Option<()
67
66
)
68
67
}
69
68
70
- fn try_merge_trees ( old : & ast:: UseTree , new : & ast:: UseTree ) -> Option < ast:: UseTree > {
71
- let lhs_path = old. path ( ) ?;
72
- let rhs_path = new. path ( ) ?;
73
-
74
- let ( lhs_prefix, rhs_prefix) = common_prefix ( & lhs_path, & rhs_path) ?;
75
-
76
- let lhs = old. split_prefix ( & lhs_prefix) ;
77
- let rhs = new. split_prefix ( & rhs_prefix) ;
78
-
79
- let should_insert_comma = lhs
80
- . use_tree_list ( ) ?
81
- . r_curly_token ( )
82
- . and_then ( |it| skip_trivia_token ( it. prev_token ( ) ?, Direction :: Prev ) )
83
- . map ( |it| it. kind ( ) != T ! [ , ] )
84
- . unwrap_or ( true ) ;
85
-
86
- let mut to_insert: Vec < SyntaxElement > = Vec :: new ( ) ;
87
- if should_insert_comma {
88
- to_insert. push ( make:: token ( T ! [ , ] ) . into ( ) ) ;
89
- to_insert. push ( make:: tokens:: single_space ( ) . into ( ) ) ;
90
- }
91
- to_insert. extend (
92
- rhs. use_tree_list ( ) ?
93
- . syntax ( )
94
- . children_with_tokens ( )
95
- . filter ( |it| it. kind ( ) != T ! [ '{' ] && it. kind ( ) != T ! [ '}' ] ) ,
96
- ) ;
97
- let use_tree_list = lhs. use_tree_list ( ) ?;
98
- let pos = InsertPosition :: Before ( use_tree_list. r_curly_token ( ) ?. into ( ) ) ;
99
- let use_tree_list = use_tree_list. insert_children ( pos, to_insert) ;
100
- Some ( lhs. with_use_tree_list ( use_tree_list) )
101
- }
102
-
103
- fn common_prefix ( lhs : & ast:: Path , rhs : & ast:: Path ) -> Option < ( ast:: Path , ast:: Path ) > {
104
- let mut res = None ;
105
- let mut lhs_curr = first_path ( & lhs) ;
106
- let mut rhs_curr = first_path ( & rhs) ;
107
- loop {
108
- match ( lhs_curr. segment ( ) , rhs_curr. segment ( ) ) {
109
- ( Some ( lhs) , Some ( rhs) ) if lhs. syntax ( ) . text ( ) == rhs. syntax ( ) . text ( ) => ( ) ,
110
- _ => break ,
111
- }
112
- res = Some ( ( lhs_curr. clone ( ) , rhs_curr. clone ( ) ) ) ;
113
-
114
- match ( lhs_curr. parent_path ( ) , rhs_curr. parent_path ( ) ) {
115
- ( Some ( lhs) , Some ( rhs) ) => {
116
- lhs_curr = lhs;
117
- rhs_curr = rhs;
118
- }
119
- _ => break ,
120
- }
121
- }
122
-
123
- res
124
- }
125
-
126
- fn first_path ( path : & ast:: Path ) -> ast:: Path {
127
- successors ( Some ( path. clone ( ) ) , |it| it. qualifier ( ) ) . last ( ) . unwrap ( )
128
- }
129
-
130
69
#[ cfg( test) ]
131
70
mod tests {
132
71
use crate :: tests:: { check_assist, check_assist_not_applicable} ;
@@ -188,6 +127,78 @@ use std::{fmt::{Display, self}};
188
127
) ;
189
128
}
190
129
130
+ #[ test]
131
+ fn skip_pub1 ( ) {
132
+ check_assist_not_applicable (
133
+ merge_imports,
134
+ r"
135
+ pub use std::fmt<|>::Debug;
136
+ use std::fmt::Display;
137
+ " ,
138
+ ) ;
139
+ }
140
+
141
+ #[ test]
142
+ fn skip_pub_last ( ) {
143
+ check_assist_not_applicable (
144
+ merge_imports,
145
+ r"
146
+ use std::fmt<|>::Debug;
147
+ pub use std::fmt::Display;
148
+ " ,
149
+ ) ;
150
+ }
151
+
152
+ #[ test]
153
+ fn skip_pub_crate_pub ( ) {
154
+ check_assist_not_applicable (
155
+ merge_imports,
156
+ r"
157
+ pub(crate) use std::fmt<|>::Debug;
158
+ pub use std::fmt::Display;
159
+ " ,
160
+ ) ;
161
+ }
162
+
163
+ #[ test]
164
+ fn skip_pub_pub_crate ( ) {
165
+ check_assist_not_applicable (
166
+ merge_imports,
167
+ r"
168
+ pub use std::fmt<|>::Debug;
169
+ pub(crate) use std::fmt::Display;
170
+ " ,
171
+ ) ;
172
+ }
173
+
174
+ #[ test]
175
+ fn merge_pub ( ) {
176
+ check_assist (
177
+ merge_imports,
178
+ r"
179
+ pub use std::fmt<|>::Debug;
180
+ pub use std::fmt::Display;
181
+ " ,
182
+ r"
183
+ pub use std::fmt::{Debug, Display};
184
+ " ,
185
+ )
186
+ }
187
+
188
+ #[ test]
189
+ fn merge_pub_crate ( ) {
190
+ check_assist (
191
+ merge_imports,
192
+ r"
193
+ pub(crate) use std::fmt<|>::Debug;
194
+ pub(crate) use std::fmt::Display;
195
+ " ,
196
+ r"
197
+ pub(crate) use std::fmt::{Debug, Display};
198
+ " ,
199
+ )
200
+ }
201
+
191
202
#[ test]
192
203
fn test_merge_nested ( ) {
193
204
check_assist (
0 commit comments