Skip to content

Commit ee9b0c8

Browse files
committed
auto_import: struct variants for ImportAction
1 parent 1866fb2 commit ee9b0c8

File tree

1 file changed

+107
-44
lines changed

1 file changed

+107
-44
lines changed

crates/ra_assists/src/auto_import.rs

+107-44
Original file line numberDiff line numberDiff line change
@@ -140,30 +140,64 @@ fn compare_path_segment_with_name(a: &ast::PathSegment, b: &ast::Name) -> bool {
140140
enum ImportAction<'a> {
141141
Nothing,
142142
// Add a brand new use statement.
143-
AddNewUse(
144-
Option<&'a SyntaxNode>, // anchor node
145-
bool, // true if we want to add the new statement after the anchor
146-
),
147-
148-
// In the following actions we keep track of how may segments matched,
149-
// so we can choose the best action to take.
143+
AddNewUse {
144+
anchor: Option<&'a SyntaxNode>, // anchor node
145+
add_after_anchor: bool,
146+
},
150147

151148
// To split an existing use statement creating a nested import.
152-
AddNestedImport(
153-
usize,
154-
&'a ast::Path, // the complete path we want to split
155-
Option<&'a ast::PathSegment>, // the first segment of path we want to add into the new nested list
156-
bool, // true if we want to add 'self' in addition to the segment
157-
),
149+
AddNestedImport {
150+
// how may segments matched with the target path
151+
common_segments: usize,
152+
path_to_split: &'a ast::Path,
153+
// the first segment of path_to_split we want to add into the new nested list
154+
first_segment_to_split: Option<&'a ast::PathSegment>,
155+
// Wether to add 'self' in addition to the target path
156+
add_self: bool,
157+
},
158158
// To add the target path to an existing nested import tree list.
159-
AddInTreeList(
160-
usize,
161-
&'a ast::UseTreeList,
162-
bool, // true if we want to add 'self'
163-
),
159+
AddInTreeList {
160+
common_segments: usize,
161+
// The UseTreeList where to add the target path
162+
tree_list: &'a ast::UseTreeList,
163+
add_self: bool,
164+
},
164165
}
165166

166167
impl<'a> ImportAction<'a> {
168+
fn add_new_use(anchor: Option<&'a SyntaxNode>, add_after_anchor: bool) -> Self {
169+
ImportAction::AddNewUse {
170+
anchor,
171+
add_after_anchor,
172+
}
173+
}
174+
175+
fn add_nested_import(
176+
common_segments: usize,
177+
path_to_split: &'a ast::Path,
178+
first_segment_to_split: Option<&'a ast::PathSegment>,
179+
add_self: bool,
180+
) -> Self {
181+
ImportAction::AddNestedImport {
182+
common_segments,
183+
path_to_split,
184+
first_segment_to_split,
185+
add_self,
186+
}
187+
}
188+
189+
fn add_in_tree_list(
190+
common_segments: usize,
191+
tree_list: &'a ast::UseTreeList,
192+
add_self: bool,
193+
) -> Self {
194+
ImportAction::AddInTreeList {
195+
common_segments,
196+
tree_list,
197+
add_self,
198+
}
199+
}
200+
167201
fn better<'b>(left: &'b ImportAction<'a>, right: &'b ImportAction<'a>) -> &'b ImportAction<'a> {
168202
if left.is_better(right) {
169203
left
@@ -175,13 +209,27 @@ impl<'a> ImportAction<'a> {
175209
fn is_better(&self, other: &ImportAction) -> bool {
176210
match (self, other) {
177211
(ImportAction::Nothing, _) => true,
178-
(ImportAction::AddInTreeList(..), ImportAction::Nothing) => false,
179-
(ImportAction::AddNestedImport(n, ..), ImportAction::AddInTreeList(m, ..)) => n > m,
180-
(ImportAction::AddInTreeList(n, ..), ImportAction::AddNestedImport(m, ..)) => n > m,
181-
(ImportAction::AddInTreeList(..), _) => true,
182-
(ImportAction::AddNestedImport(..), ImportAction::Nothing) => false,
183-
(ImportAction::AddNestedImport(..), _) => true,
184-
(ImportAction::AddNewUse(..), _) => false,
212+
(ImportAction::AddInTreeList { .. }, ImportAction::Nothing) => false,
213+
(
214+
ImportAction::AddNestedImport {
215+
common_segments: n, ..
216+
},
217+
ImportAction::AddInTreeList {
218+
common_segments: m, ..
219+
},
220+
) => n > m,
221+
(
222+
ImportAction::AddInTreeList {
223+
common_segments: n, ..
224+
},
225+
ImportAction::AddNestedImport {
226+
common_segments: m, ..
227+
},
228+
) => n > m,
229+
(ImportAction::AddInTreeList { .. }, _) => true,
230+
(ImportAction::AddNestedImport { .. }, ImportAction::Nothing) => false,
231+
(ImportAction::AddNestedImport { .. }, _) => true,
232+
(ImportAction::AddNewUse { .. }, _) => false,
185233
}
186234
}
187235
}
@@ -205,7 +253,7 @@ fn walk_use_tree_for_best_action<'a>(
205253
Some(path) => path,
206254
None => {
207255
// If the use item don't have a path, it means it's broken (syntax error)
208-
return ImportAction::AddNewUse(
256+
return ImportAction::add_new_use(
209257
current_use_tree
210258
.syntax()
211259
.ancestors()
@@ -231,7 +279,7 @@ fn walk_use_tree_for_best_action<'a>(
231279
let right = current_path_segments.split_at(prev_len).1;
232280
let common = compare_path_segments(left, right);
233281
let mut action = match common {
234-
0 => ImportAction::AddNewUse(
282+
0 => ImportAction::add_new_use(
235283
// e.g: target is std::fmt and we can have
236284
// use foo::bar
237285
// We add a brand new use statement
@@ -259,7 +307,7 @@ fn walk_use_tree_for_best_action<'a>(
259307
if has_self {
260308
ImportAction::Nothing
261309
} else {
262-
ImportAction::AddInTreeList(current_path_segments.len(), list, true)
310+
ImportAction::add_in_tree_list(current_path_segments.len(), list, true)
263311
}
264312
} else {
265313
// Case 1
@@ -271,7 +319,7 @@ fn walk_use_tree_for_best_action<'a>(
271319
// use std::io;
272320
// We need to split.
273321
let segments_to_split = current_path_segments.split_at(prev_len + common).1;
274-
ImportAction::AddNestedImport(
322+
ImportAction::add_nested_import(
275323
prev_len + common,
276324
path,
277325
Some(segments_to_split[0]),
@@ -284,7 +332,7 @@ fn walk_use_tree_for_best_action<'a>(
284332
// 2- use std::{ ... };
285333

286334
// fallback action
287-
let mut better_action = ImportAction::AddNewUse(
335+
let mut better_action = ImportAction::add_new_use(
288336
current_use_tree
289337
.syntax()
290338
.ancestors()
@@ -306,24 +354,29 @@ fn walk_use_tree_for_best_action<'a>(
306354
}
307355
} else {
308356
// Case 1, split
309-
better_action = ImportAction::AddNestedImport(prev_len + common, path, None, true)
357+
better_action = ImportAction::add_nested_import(prev_len + common, path, None, true)
310358
}
311359
better_action
312360
}
313361
common if left.len() < right.len() => {
314362
// e.g: target is std::fmt and we can have
315363
// use std::fmt::Debug;
316364
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)
365+
ImportAction::add_nested_import(
366+
prev_len + common,
367+
path,
368+
Some(segments_to_split[0]),
369+
true,
370+
)
318371
}
319372
_ => unreachable!(),
320373
};
321374

322375
// If we are inside a UseTreeList adding a use statement become adding to the existing
323376
// tree list.
324377
action = match (current_parent_use_tree_list, action) {
325-
(Some(use_tree_list), ImportAction::AddNewUse(..)) => {
326-
ImportAction::AddInTreeList(prev_len, use_tree_list, false)
378+
(Some(use_tree_list), ImportAction::AddNewUse { .. }) => {
379+
ImportAction::add_in_tree_list(prev_len, use_tree_list, false)
327380
}
328381
(_, _) => action,
329382
};
@@ -361,26 +414,36 @@ fn best_action_for_target<'b, 'a: 'b>(
361414
.map(AstNode::syntax)
362415
.or(Some(path.syntax()));
363416

364-
return ImportAction::AddNewUse(anchor, false);
417+
return ImportAction::add_new_use(anchor, false);
365418
}
366419
}
367420
}
368421

369422
fn make_assist(action: &ImportAction, target: &[&ast::PathSegment], edit: &mut AssistBuilder) {
370423
match action {
371-
ImportAction::AddNewUse(anchor, after) => {
372-
make_assist_add_new_use(anchor, *after, target, edit)
373-
}
374-
ImportAction::AddInTreeList(n, tree_list_node, add_self) => {
424+
ImportAction::AddNewUse {
425+
anchor,
426+
add_after_anchor,
427+
} => make_assist_add_new_use(anchor, *add_after_anchor, target, edit),
428+
ImportAction::AddInTreeList {
429+
common_segments,
430+
tree_list,
431+
add_self,
432+
} => {
375433
// We know that the fist n segments already exists in the use statement we want
376434
// to modify, so we want to add only the last target.len() - n segments.
377-
let segments_to_add = target.split_at(*n).1;
378-
make_assist_add_in_tree_list(tree_list_node, segments_to_add, *add_self, edit)
435+
let segments_to_add = target.split_at(*common_segments).1;
436+
make_assist_add_in_tree_list(tree_list, segments_to_add, *add_self, edit)
379437
}
380-
ImportAction::AddNestedImport(n, path, first_segment_to_split, add_self) => {
381-
let segments_to_add = target.split_at(*n).1;
438+
ImportAction::AddNestedImport {
439+
common_segments,
440+
path_to_split,
441+
first_segment_to_split,
442+
add_self,
443+
} => {
444+
let segments_to_add = target.split_at(*common_segments).1;
382445
make_assist_add_nested_import(
383-
path,
446+
path_to_split,
384447
first_segment_to_split,
385448
segments_to_add,
386449
*add_self,

0 commit comments

Comments
 (0)