@@ -4,7 +4,6 @@ use ra_syntax::{
4
4
SyntaxKind :: { PATH , PATH_SEGMENT , COLONCOLON , COMMA }
5
5
} ;
6
6
use crate :: assist_ctx:: { AssistCtx , Assist , AssistBuilder } ;
7
- use itertools:: { Itertools , EitherOrBoth } ;
8
7
9
8
// TODO: refactor this before merge
10
9
mod formatting {
@@ -101,44 +100,13 @@ fn fmt_segments_raw(segments: &[&ast::PathSegment], buf: &mut String) {
101
100
}
102
101
}
103
102
104
- #[ derive( Copy , Clone ) ]
105
- enum PathSegmentsMatch {
106
- // Patch matches exactly
107
- Full ,
108
- // When some of the segments matched
109
- Partial ( usize ) ,
110
- // When all the segments of the right path are matched against the left path,
111
- // but the left path is longer.
112
- PartialLeft ( usize ) ,
113
- // When all the segments of the left path are matched against the right path,
114
- // but the right path is longer.
115
- PartialRight ( usize ) ,
116
- // In all the three cases above we keep track of how many segments matched
117
- }
118
-
119
- fn compare_path_segments (
120
- left : & [ & ast:: PathSegment ] ,
121
- right : & [ & ast:: PathSegment ] ,
122
- ) -> PathSegmentsMatch {
123
- let mut matching = 0 ;
124
- for either_or_both in left. iter ( ) . zip_longest ( right. iter ( ) ) {
125
- match either_or_both {
126
- EitherOrBoth :: Both ( left, right) => {
127
- if compare_path_segment ( left, right) {
128
- matching += 1
129
- } else {
130
- return PathSegmentsMatch :: Partial ( matching) ;
131
- }
132
- }
133
- EitherOrBoth :: Left ( _) => {
134
- return PathSegmentsMatch :: PartialLeft ( matching) ;
135
- }
136
- EitherOrBoth :: Right ( _) => {
137
- return PathSegmentsMatch :: PartialRight ( matching) ;
138
- }
139
- }
140
- }
141
- return PathSegmentsMatch :: Full ;
103
+ // Returns the numeber of common segments.
104
+ fn compare_path_segments ( left : & [ & ast:: PathSegment ] , right : & [ & ast:: PathSegment ] ) -> usize {
105
+ return left
106
+ . iter ( )
107
+ . zip ( right)
108
+ . filter ( |( l, r) | compare_path_segment ( l, r) )
109
+ . count ( ) ;
142
110
}
143
111
144
112
fn compare_path_segment ( a : & ast:: PathSegment , b : & ast:: PathSegment ) -> bool {
@@ -259,13 +227,22 @@ fn walk_use_tree_for_best_action<'a>(
259
227
260
228
// We compare only the new segments added in the line just above.
261
229
// The first prev_len segments were already compared in 'parent' recursive calls.
262
- let c = compare_path_segments (
263
- target. split_at ( prev_len) . 1 ,
264
- current_path_segments. split_at ( prev_len) . 1 ,
265
- ) ;
266
-
267
- let mut action = match c {
268
- PathSegmentsMatch :: Full => {
230
+ let left = target. split_at ( prev_len) . 1 ;
231
+ let right = current_path_segments. split_at ( prev_len) . 1 ;
232
+ let common = compare_path_segments ( left, right) ;
233
+ let mut action = match common {
234
+ 0 => ImportAction :: AddNewUse (
235
+ // e.g: target is std::fmt and we can have
236
+ // use foo::bar
237
+ // We add a brand new use statement
238
+ current_use_tree
239
+ . syntax ( )
240
+ . ancestors ( )
241
+ . find_map ( ast:: UseItem :: cast)
242
+ . map ( AstNode :: syntax) ,
243
+ true ,
244
+ ) ,
245
+ common if common == left. len ( ) && left. len ( ) == right. len ( ) => {
269
246
// e.g: target is std::fmt and we can have
270
247
// 1- use std::fmt;
271
248
// 2- use std::fmt:{ ... }
@@ -289,25 +266,19 @@ fn walk_use_tree_for_best_action<'a>(
289
266
ImportAction :: Nothing
290
267
}
291
268
}
292
- PathSegmentsMatch :: Partial ( 0 ) => ImportAction :: AddNewUse (
293
- // e.g: target is std::fmt and we can have
294
- // use foo::bar
295
- // We add a brand new use statement
296
- current_use_tree
297
- . syntax ( )
298
- . ancestors ( )
299
- . find_map ( ast:: UseItem :: cast)
300
- . map ( AstNode :: syntax) ,
301
- true ,
302
- ) ,
303
- PathSegmentsMatch :: Partial ( n) => {
269
+ common if common != left. len ( ) && left. len ( ) == right. len ( ) => {
304
270
// e.g: target is std::fmt and we have
305
271
// use std::io;
306
272
// We need to split.
307
- let segments_to_split = current_path_segments. split_at ( prev_len + n) . 1 ;
308
- ImportAction :: AddNestedImport ( prev_len + n, path, Some ( segments_to_split[ 0 ] ) , false )
273
+ let segments_to_split = current_path_segments. split_at ( prev_len + common) . 1 ;
274
+ ImportAction :: AddNestedImport (
275
+ prev_len + common,
276
+ path,
277
+ Some ( segments_to_split[ 0 ] ) ,
278
+ false ,
279
+ )
309
280
}
310
- PathSegmentsMatch :: PartialLeft ( n ) => {
281
+ common if left . len ( ) > right . len ( ) => {
311
282
// e.g: target is std::fmt and we can have
312
283
// 1- use std;
313
284
// 2- use std::{ ... };
@@ -335,16 +306,17 @@ fn walk_use_tree_for_best_action<'a>(
335
306
}
336
307
} else {
337
308
// Case 1, split
338
- better_action = ImportAction :: AddNestedImport ( prev_len + n , path, None , true )
309
+ better_action = ImportAction :: AddNestedImport ( prev_len + common , path, None , true )
339
310
}
340
311
better_action
341
312
}
342
- PathSegmentsMatch :: PartialRight ( n ) => {
313
+ common if left . len ( ) < right . len ( ) => {
343
314
// e.g: target is std::fmt and we can have
344
315
// use std::fmt::Debug;
345
- let segments_to_split = current_path_segments. split_at ( prev_len + n ) . 1 ;
346
- ImportAction :: AddNestedImport ( prev_len + n , path, Some ( segments_to_split[ 0 ] ) , true )
316
+ let segments_to_split = current_path_segments. split_at ( prev_len + common ) . 1 ;
317
+ ImportAction :: AddNestedImport ( prev_len + common , path, Some ( segments_to_split[ 0 ] ) , true )
347
318
}
319
+ _ => unreachable ! ( ) ,
348
320
} ;
349
321
350
322
// If we are inside a UseTreeList adding a use statement become adding to the existing
0 commit comments