Skip to content

Commit 67c1c2b

Browse files
committed
update merge item assist implementation for "one" import granularity
1 parent 7db4117 commit 67c1c2b

File tree

2 files changed

+51
-61
lines changed

2 files changed

+51
-61
lines changed

crates/ide-assists/src/handlers/merge_imports.rs

+40-61
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use Edit::*;
1919

2020
// Assist: merge_imports
2121
//
22-
// Merges two imports with a common prefix.
22+
// Merges neighbor imports with a common prefix.
2323
//
2424
// ```
2525
// use std::$0fmt::Formatter;
@@ -32,37 +32,23 @@ use Edit::*;
3232
pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
3333
let (target, edits) = if ctx.has_empty_selection() {
3434
// Merge a neighbor
35-
let tree: ast::UseTree = ctx.find_node_at_offset()?;
36-
let mut target = tree.syntax().text_range();
35+
let mut tree: ast::UseTree = ctx.find_node_at_offset()?;
36+
if ctx.config.insert_use.granularity == ImportGranularity::One
37+
&& tree.parent_use_tree_list().is_some()
38+
{
39+
cov_mark::hit!(resolve_top_use_tree_for_import_one);
40+
tree = tree.top_use_tree();
41+
}
42+
let target = tree.syntax().text_range();
3743

3844
let edits = if let Some(use_item) = tree.syntax().parent().and_then(ast::Use::cast) {
45+
cov_mark::hit!(merge_with_use_item_neighbors);
3946
let mut neighbor = next_prev().find_map(|dir| neighbor(&use_item, dir)).into_iter();
4047
use_item.try_merge_from(&mut neighbor, &ctx.config.insert_use)
4148
} else {
49+
cov_mark::hit!(merge_with_use_tree_neighbors);
4250
let mut neighbor = next_prev().find_map(|dir| neighbor(&tree, dir)).into_iter();
43-
let mut edits = tree.clone().try_merge_from(&mut neighbor, &ctx.config.insert_use);
44-
45-
if edits.is_none() && ctx.config.insert_use.granularity == ImportGranularity::One {
46-
let one_tree = tree
47-
.parent_use_tree_list()
48-
.map(|it| it.parent_use_tree().top_use_tree())
49-
.filter(|top_tree| top_tree.path().is_none())
50-
.and_then(|one_tree| {
51-
one_tree.syntax().parent().and_then(ast::Use::cast).zip(Some(one_tree))
52-
});
53-
if let Some((use_item, one_tree)) = one_tree {
54-
let mut neighbor = next_prev()
55-
.find_map(|dir| syntax::algo::neighbor(&use_item, dir))
56-
.into_iter();
57-
edits = use_item.try_merge_from(&mut neighbor, &ctx.config.insert_use);
58-
59-
if edits.is_some() {
60-
target = one_tree.syntax().text_range();
61-
}
62-
}
63-
}
64-
65-
edits
51+
tree.clone().try_merge_from(&mut neighbor, &ctx.config.insert_use)
6652
};
6753
(target, edits?)
6854
} else {
@@ -79,9 +65,11 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
7965
let edits = match_ast! {
8066
match first_selected {
8167
ast::Use(use_item) => {
68+
cov_mark::hit!(merge_with_selected_use_item_neighbors);
8269
use_item.try_merge_from(&mut selected_nodes.filter_map(ast::Use::cast), &ctx.config.insert_use)
8370
},
8471
ast::UseTree(use_tree) => {
72+
cov_mark::hit!(merge_with_selected_use_tree_neighbors);
8573
use_tree.try_merge_from(&mut selected_nodes.filter_map(ast::UseTree::cast), &ctx.config.insert_use)
8674
},
8775
_ => return None,
@@ -171,7 +159,10 @@ impl Edit {
171159

172160
#[cfg(test)]
173161
mod tests {
174-
use crate::tests::{check_assist, check_assist_import_one, check_assist_not_applicable};
162+
use crate::tests::{
163+
check_assist, check_assist_import_one, check_assist_not_applicable,
164+
check_assist_not_applicable_for_import_one,
165+
};
175166

176167
use super::*;
177168

@@ -202,6 +193,7 @@ mod tests {
202193

203194
#[test]
204195
fn test_merge_equal() {
196+
cov_mark::check!(merge_with_use_item_neighbors);
205197
check_assist(
206198
merge_imports,
207199
r"
@@ -212,6 +204,13 @@ use std::fmt::{Display, Debug};
212204
use std::fmt::{Display, Debug};
213205
",
214206
);
207+
208+
// The assist macro below calls `check_assist_import_one` 4 times with different input
209+
// use item variations based on the first 2 input parameters, but only 2 calls
210+
// contain `use {std::fmt$0::{Display, Debug}};` for which the top use tree will need
211+
// to be resolved.
212+
cov_mark::check_count!(resolve_top_use_tree_for_import_one, 2);
213+
cov_mark::check_count!(merge_with_use_item_neighbors, 4);
215214
check_assist_import_one_variations!(
216215
"std::fmt$0::{Display, Debug}",
217216
"std::fmt::{Display, Debug}",
@@ -287,14 +286,14 @@ use std::{fmt, $0fmt::Display};
287286
use std::{fmt::{self, Display}};
288287
",
289288
);
290-
check_assist_import_one(
289+
}
290+
291+
#[test]
292+
fn not_applicable_to_single_one_style_import() {
293+
cov_mark::check!(resolve_top_use_tree_for_import_one);
294+
check_assist_not_applicable_for_import_one(
291295
merge_imports,
292-
r"
293-
use {std::{fmt, $0fmt::Display}};
294-
",
295-
r"
296-
use {std::{fmt::{self, Display}}};
297-
",
296+
"use {std::{fmt, $0fmt::Display}};",
298297
);
299298
}
300299

@@ -386,22 +385,14 @@ pub(in this::path) use std::fmt::{Debug, Display};
386385

387386
#[test]
388387
fn test_merge_nested() {
388+
cov_mark::check!(merge_with_use_tree_neighbors);
389389
check_assist(
390390
merge_imports,
391391
r"
392392
use std::{fmt$0::Debug, fmt::Display};
393393
",
394394
r"
395395
use std::{fmt::{Debug, Display}};
396-
",
397-
);
398-
check_assist_import_one(
399-
merge_imports,
400-
r"
401-
use {std::{fmt$0::Debug, fmt::Display}};
402-
",
403-
r"
404-
use {std::{fmt::{Debug, Display}}};
405396
",
406397
);
407398
}
@@ -415,15 +406,6 @@ use std::{fmt::Debug, fmt$0::Display};
415406
",
416407
r"
417408
use std::{fmt::{Debug, Display}};
418-
",
419-
);
420-
check_assist_import_one(
421-
merge_imports,
422-
r"
423-
use {std::{fmt::Debug, fmt$0::Display}};
424-
",
425-
r"
426-
use {std::{fmt::{Debug, Display}}};
427409
",
428410
);
429411
}
@@ -475,15 +457,6 @@ use std::{fmt$0::{self, Debug}, fmt::{Write, Display}};
475457
",
476458
r"
477459
use std::{fmt::{self, Debug, Display, Write}};
478-
",
479-
);
480-
check_assist_import_one(
481-
merge_imports,
482-
r"
483-
use {std::{fmt$0::{self, Debug}, fmt::{Write, Display}}};
484-
",
485-
r"
486-
use {std::{fmt::{self, Debug, Display, Write}}};
487460
",
488461
);
489462
}
@@ -682,6 +655,7 @@ use foo::{bar::Baz, *};
682655

683656
#[test]
684657
fn merge_selection_uses() {
658+
cov_mark::check!(merge_with_selected_use_item_neighbors);
685659
check_assist(
686660
merge_imports,
687661
r"
@@ -697,6 +671,8 @@ use std::fmt::{Debug, Display, Write};
697671
use std::fmt::Result;
698672
",
699673
);
674+
675+
cov_mark::check!(merge_with_selected_use_item_neighbors);
700676
check_assist_import_one(
701677
merge_imports,
702678
r"
@@ -716,6 +692,7 @@ use std::fmt::Result;
716692

717693
#[test]
718694
fn merge_selection_use_trees() {
695+
cov_mark::check!(merge_with_selected_use_tree_neighbors);
719696
check_assist(
720697
merge_imports,
721698
r"
@@ -733,7 +710,9 @@ use std::{
733710
fmt::Result,
734711
};",
735712
);
713+
736714
// FIXME: Remove redundant braces. See also unnecessary-braces diagnostic.
715+
cov_mark::check!(merge_with_selected_use_tree_neighbors);
737716
check_assist(
738717
merge_imports,
739718
r"use std::$0{fmt::Display, fmt::Debug}$0;",

crates/ide-assists/src/tests.rs

+11
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,17 @@ pub(crate) fn check_assist_not_applicable_by_label(assist: Handler, ra_fixture:
137137
check(assist, ra_fixture, ExpectedResult::NotApplicable, Some(label));
138138
}
139139

140+
#[track_caller]
141+
pub(crate) fn check_assist_not_applicable_for_import_one(assist: Handler, ra_fixture: &str) {
142+
check_with_config(
143+
TEST_CONFIG_IMPORT_ONE,
144+
assist,
145+
ra_fixture,
146+
ExpectedResult::NotApplicable,
147+
None,
148+
);
149+
}
150+
140151
/// Check assist in unresolved state. Useful to check assists for lazy computation.
141152
#[track_caller]
142153
pub(crate) fn check_assist_unresolved(assist: Handler, ra_fixture: &str) {

0 commit comments

Comments
 (0)