@@ -4,7 +4,7 @@ use ide_db::{
4
4
defs:: { classify_name_ref, Definition , NameRefClass } ,
5
5
RootDatabase ,
6
6
} ;
7
- use syntax:: { algo , ast, match_ast , AstNode , SyntaxNode , SyntaxToken , T } ;
7
+ use syntax:: { ast, AstNode , SyntaxToken , T } ;
8
8
9
9
use crate :: {
10
10
assist_context:: { AssistBuilder , AssistContext , Assists } ,
@@ -38,7 +38,7 @@ use crate::{
38
38
// ```
39
39
pub ( crate ) fn expand_glob_import ( acc : & mut Assists , ctx : & AssistContext ) -> Option < ( ) > {
40
40
let star = ctx. find_token_at_offset ( T ! [ * ] ) ?;
41
- let mod_path = find_mod_path ( & star) ?;
41
+ let ( parent , mod_path) = find_parent_and_path ( & star) ?;
42
42
let module = match ctx. sema . resolve_path ( & mod_path) ? {
43
43
PathResolution :: Def ( ModuleDef :: Module ( it) ) => it,
44
44
_ => return None ,
@@ -52,19 +52,23 @@ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Opti
52
52
source_file. syntax ( ) . descendants ( ) . filter_map ( ast:: NameRef :: cast) . collect ( ) ;
53
53
let used_names = find_used_names ( ctx, defs_in_mod, name_refs_in_source_file) ;
54
54
55
- let parent = star . parent ( ) . parent ( ) ? ;
55
+ let target = parent. syntax ( ) ;
56
56
acc. add (
57
57
AssistId ( "expand_glob_import" , AssistKind :: RefactorRewrite ) ,
58
58
"Expand glob import" ,
59
- parent . text_range ( ) ,
59
+ target . text_range ( ) ,
60
60
|builder| {
61
- replace_ast ( builder, & parent, mod_path, used_names) ;
61
+ replace_ast ( builder, parent, mod_path, used_names) ;
62
62
} ,
63
63
)
64
64
}
65
65
66
- fn find_mod_path ( star : & SyntaxToken ) -> Option < ast:: Path > {
67
- star. ancestors ( ) . find_map ( |n| ast:: UseTree :: cast ( n) . and_then ( |u| u. path ( ) ) )
66
+ fn find_parent_and_path ( star : & SyntaxToken ) -> Option < ( ast:: UseTree , ast:: Path ) > {
67
+ star. ancestors ( ) . find_map ( |n| {
68
+ let use_tree = ast:: UseTree :: cast ( n) ?;
69
+ let path = use_tree. path ( ) ?;
70
+ Some ( ( use_tree, path) )
71
+ } )
68
72
}
69
73
70
74
#[ derive( PartialEq ) ]
@@ -137,41 +141,28 @@ fn find_used_names(
137
141
138
142
fn replace_ast (
139
143
builder : & mut AssistBuilder ,
140
- node : & SyntaxNode ,
144
+ parent : ast :: UseTree ,
141
145
path : ast:: Path ,
142
146
used_names : Vec < Name > ,
143
147
) {
144
- let replacement: Either < ast :: UseTree , ast :: UseTreeList > = match used_names. as_slice ( ) {
145
- [ name] => Either :: Left ( ast:: make:: use_tree (
148
+ let replacement = match used_names. as_slice ( ) {
149
+ [ name] => ast:: make:: use_tree (
146
150
ast:: make:: path_from_text ( & format ! ( "{}::{}" , path, name) ) ,
147
151
None ,
148
152
None ,
149
153
false ,
150
- ) ) ,
151
- names => Either :: Right ( ast:: make:: use_tree_list ( names . iter ( ) . map ( |n| {
152
- ast :: make :: use_tree ( ast :: make :: path_from_text ( & n . to_string ( ) ) , None , None , false )
153
- } ) ) ) ,
154
- } ;
155
-
156
- let mut replace_node = | replacement : Either < ast :: UseTree , ast :: UseTreeList > | {
157
- algo :: diff ( node , & replacement . either ( |u| u . syntax ( ) . clone ( ) , |ut| ut . syntax ( ) . clone ( ) ) )
158
- . into_text_edit ( builder . text_edit_builder ( ) ) ;
154
+ ) ,
155
+ names => ast:: make:: use_tree (
156
+ path ,
157
+ Some ( ast :: make :: use_tree_list ( names . iter ( ) . map ( |n| {
158
+ ast :: make :: use_tree ( ast :: make :: path_from_text ( & n . to_string ( ) ) , None , None , false )
159
+ } ) ) ) ,
160
+ None ,
161
+ false ,
162
+ ) ,
159
163
} ;
160
164
161
- match_ast ! {
162
- match node {
163
- ast:: UseTree ( use_tree) => {
164
- replace_node( replacement) ;
165
- } ,
166
- ast:: UseTreeList ( use_tree_list) => {
167
- replace_node( replacement) ;
168
- } ,
169
- ast:: Use ( use_item) => {
170
- builder. replace_ast( use_item, ast:: make:: use_( replacement. left_or_else( |ut| ast:: make:: use_tree( path, Some ( ut) , None , false ) ) ) ) ;
171
- } ,
172
- _ => { } ,
173
- }
174
- }
165
+ builder. replace_ast ( parent, replacement) ;
175
166
}
176
167
177
168
#[ cfg( test) ]
@@ -260,15 +251,15 @@ fn qux(bar: Bar, baz: Baz) {
260
251
expand_glob_import,
261
252
r"
262
253
mod foo {
263
- mod bar {
254
+ pub mod bar {
264
255
pub struct Bar;
265
256
pub struct Baz;
266
257
pub struct Qux;
267
258
268
259
pub fn f() {}
269
260
}
270
261
271
- mod baz {
262
+ pub mod baz {
272
263
pub fn g() {}
273
264
}
274
265
}
@@ -282,15 +273,15 @@ fn qux(bar: Bar, baz: Baz) {
282
273
" ,
283
274
r"
284
275
mod foo {
285
- mod bar {
276
+ pub mod bar {
286
277
pub struct Bar;
287
278
pub struct Baz;
288
279
pub struct Qux;
289
280
290
281
pub fn f() {}
291
282
}
292
283
293
- mod baz {
284
+ pub mod baz {
294
285
pub fn g() {}
295
286
}
296
287
}
@@ -302,7 +293,207 @@ fn qux(bar: Bar, baz: Baz) {
302
293
g();
303
294
}
304
295
" ,
305
- )
296
+ ) ;
297
+
298
+ check_assist (
299
+ expand_glob_import,
300
+ r"
301
+ mod foo {
302
+ pub mod bar {
303
+ pub struct Bar;
304
+ pub struct Baz;
305
+ pub struct Qux;
306
+
307
+ pub fn f() {}
308
+ }
309
+
310
+ pub mod baz {
311
+ pub fn g() {}
312
+ }
313
+ }
314
+
315
+ use foo::{bar::{Bar, Baz, f}, baz::*<|>};
316
+
317
+ fn qux(bar: Bar, baz: Baz) {
318
+ f();
319
+ g();
320
+ }
321
+ " ,
322
+ r"
323
+ mod foo {
324
+ pub mod bar {
325
+ pub struct Bar;
326
+ pub struct Baz;
327
+ pub struct Qux;
328
+
329
+ pub fn f() {}
330
+ }
331
+
332
+ pub mod baz {
333
+ pub fn g() {}
334
+ }
335
+ }
336
+
337
+ use foo::{bar::{Bar, Baz, f}, baz::g};
338
+
339
+ fn qux(bar: Bar, baz: Baz) {
340
+ f();
341
+ g();
342
+ }
343
+ " ,
344
+ ) ;
345
+
346
+ check_assist (
347
+ expand_glob_import,
348
+ r"
349
+ mod foo {
350
+ pub mod bar {
351
+ pub struct Bar;
352
+ pub struct Baz;
353
+ pub struct Qux;
354
+
355
+ pub fn f() {}
356
+ }
357
+
358
+ pub mod baz {
359
+ pub fn g() {}
360
+
361
+ pub mod qux {
362
+ pub fn h() {}
363
+ pub fn m() {}
364
+
365
+ pub mod q {
366
+ pub fn j() {}
367
+ }
368
+ }
369
+ }
370
+ }
371
+
372
+ use foo::{
373
+ bar::{*, f},
374
+ baz::{g, qux::*<|>}
375
+ };
376
+
377
+ fn qux(bar: Bar, baz: Baz) {
378
+ f();
379
+ g();
380
+ h();
381
+ q::j();
382
+ }
383
+ " ,
384
+ r"
385
+ mod foo {
386
+ pub mod bar {
387
+ pub struct Bar;
388
+ pub struct Baz;
389
+ pub struct Qux;
390
+
391
+ pub fn f() {}
392
+ }
393
+
394
+ pub mod baz {
395
+ pub fn g() {}
396
+
397
+ pub mod qux {
398
+ pub fn h() {}
399
+ pub fn m() {}
400
+
401
+ pub mod q {
402
+ pub fn j() {}
403
+ }
404
+ }
405
+ }
406
+ }
407
+
408
+ use foo::{
409
+ bar::{*, f},
410
+ baz::{g, qux::{q, h}}
411
+ };
412
+
413
+ fn qux(bar: Bar, baz: Baz) {
414
+ f();
415
+ g();
416
+ h();
417
+ q::j();
418
+ }
419
+ " ,
420
+ ) ;
421
+
422
+ check_assist (
423
+ expand_glob_import,
424
+ r"
425
+ mod foo {
426
+ pub mod bar {
427
+ pub struct Bar;
428
+ pub struct Baz;
429
+ pub struct Qux;
430
+
431
+ pub fn f() {}
432
+ }
433
+
434
+ pub mod baz {
435
+ pub fn g() {}
436
+
437
+ pub mod qux {
438
+ pub fn h() {}
439
+ pub fn m() {}
440
+
441
+ pub mod q {
442
+ pub fn j() {}
443
+ }
444
+ }
445
+ }
446
+ }
447
+
448
+ use foo::{
449
+ bar::{*, f},
450
+ baz::{g, qux::{h, q::*<|>}}
451
+ };
452
+
453
+ fn qux(bar: Bar, baz: Baz) {
454
+ f();
455
+ g();
456
+ h();
457
+ j();
458
+ }
459
+ " ,
460
+ r"
461
+ mod foo {
462
+ pub mod bar {
463
+ pub struct Bar;
464
+ pub struct Baz;
465
+ pub struct Qux;
466
+
467
+ pub fn f() {}
468
+ }
469
+
470
+ pub mod baz {
471
+ pub fn g() {}
472
+
473
+ pub mod qux {
474
+ pub fn h() {}
475
+ pub fn m() {}
476
+
477
+ pub mod q {
478
+ pub fn j() {}
479
+ }
480
+ }
481
+ }
482
+ }
483
+
484
+ use foo::{
485
+ bar::{*, f},
486
+ baz::{g, qux::{h, q::j}}
487
+ };
488
+
489
+ fn qux(bar: Bar, baz: Baz) {
490
+ f();
491
+ g();
492
+ h();
493
+ j();
494
+ }
495
+ " ,
496
+ ) ;
306
497
}
307
498
308
499
#[ test]
0 commit comments