fix: splitting path of a glob import wrongly adds self
`ast::UseTree::split_prefix` handles globs now. Removed an extra branch for globs in `ide_db::imports::merge_imports::recursive_merge` (superseeded by split_prefix).
This commit is contained in:
parent
bc08b8eff3
commit
b4c608896c
@ -330,7 +330,7 @@ fn test_merge_nested_list_self_and_glob() {
|
|||||||
use std::{fmt::{self, Display}};
|
use std::{fmt::{self, Display}};
|
||||||
",
|
",
|
||||||
r"
|
r"
|
||||||
use std::{fmt::{self, *, Display}};
|
use std::{fmt::{*, self, Display}};
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -440,4 +440,18 @@ fn test_empty_use() {
|
|||||||
fn main() {}",
|
fn main() {}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn split_glob() {
|
||||||
|
check_assist(
|
||||||
|
merge_imports,
|
||||||
|
r"
|
||||||
|
use foo::$0*;
|
||||||
|
use foo::bar::Baz;
|
||||||
|
",
|
||||||
|
r"
|
||||||
|
use foo::{*, bar::Baz};
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -656,7 +656,7 @@ fn merge_mod_into_glob() {
|
|||||||
check_with_config(
|
check_with_config(
|
||||||
"token::TokenKind",
|
"token::TokenKind",
|
||||||
r"use token::TokenKind::*;",
|
r"use token::TokenKind::*;",
|
||||||
r"use token::TokenKind::{self, *};",
|
r"use token::TokenKind::{*, self};",
|
||||||
&InsertUseConfig {
|
&InsertUseConfig {
|
||||||
granularity: ImportGranularity::Crate,
|
granularity: ImportGranularity::Crate,
|
||||||
enforce_granularity: true,
|
enforce_granularity: true,
|
||||||
@ -670,11 +670,10 @@ fn merge_mod_into_glob() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn merge_self_glob() {
|
fn merge_self_glob() {
|
||||||
cov_mark::check!(merge_self_glob);
|
|
||||||
check_with_config(
|
check_with_config(
|
||||||
"self",
|
"self",
|
||||||
r"use self::*;",
|
r"use self::*;",
|
||||||
r"use self::{self, *};",
|
r"use self::{*, self};",
|
||||||
&InsertUseConfig {
|
&InsertUseConfig {
|
||||||
granularity: ImportGranularity::Crate,
|
granularity: ImportGranularity::Crate,
|
||||||
enforce_granularity: true,
|
enforce_granularity: true,
|
||||||
@ -693,7 +692,7 @@ fn merge_glob() {
|
|||||||
r"
|
r"
|
||||||
use syntax::{SyntaxKind::*};",
|
use syntax::{SyntaxKind::*};",
|
||||||
r"
|
r"
|
||||||
use syntax::{SyntaxKind::{self, *}};",
|
use syntax::{SyntaxKind::{*, self}};",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,7 +701,7 @@ fn merge_glob_nested() {
|
|||||||
check_crate(
|
check_crate(
|
||||||
"foo::bar::quux::Fez",
|
"foo::bar::quux::Fez",
|
||||||
r"use foo::bar::{Baz, quux::*};",
|
r"use foo::bar::{Baz, quux::*};",
|
||||||
r"use foo::bar::{Baz, quux::{self::*, Fez}};",
|
r"use foo::bar::{Baz, quux::{*, Fez}};",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use itertools::{EitherOrBoth, Itertools};
|
use itertools::{EitherOrBoth, Itertools};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, make, AstNode, HasAttrs, HasVisibility, PathSegmentKind},
|
ast::{self, AstNode, HasAttrs, HasVisibility, PathSegmentKind},
|
||||||
ted,
|
ted,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -129,29 +129,7 @@ fn recursive_merge(lhs: &ast::UseTree, rhs: &ast::UseTree, merge: MergeBehavior)
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Glob imports aren't part of the use-tree lists so we need
|
if lhs_t.use_tree_list().is_none() && rhs_t.use_tree_list().is_none() {
|
||||||
// to special handle them here as well this special handling
|
|
||||||
// is only required for when we merge a module import into a
|
|
||||||
// glob import of said module see the `merge_self_glob` or
|
|
||||||
// `merge_mod_into_glob` tests.
|
|
||||||
if lhs_t.star_token().is_some() || rhs_t.star_token().is_some() {
|
|
||||||
if tree_is_self(lhs_t) || tree_is_self(&rhs_t) {
|
|
||||||
cov_mark::hit!(merge_self_glob);
|
|
||||||
let self_tree = make::use_tree(
|
|
||||||
make::path_unqualified(make::path_segment_self()),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.clone_for_update();
|
|
||||||
ted::replace(lhs_t.syntax(), self_tree.syntax());
|
|
||||||
*lhs_t = self_tree;
|
|
||||||
let glob = make::use_tree_glob().clone_for_update();
|
|
||||||
use_trees.insert(idx, glob.clone());
|
|
||||||
lhs.get_or_create_use_tree_list().add_use_tree(glob);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else if lhs_t.use_tree_list().is_none() && rhs_t.use_tree_list().is_none() {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,16 +302,33 @@ pub fn get_or_create_use_tree_list(&self) -> ast::UseTreeList {
|
|||||||
|
|
||||||
/// Splits off the given prefix, making it the path component of the use tree,
|
/// Splits off the given prefix, making it the path component of the use tree,
|
||||||
/// appending the rest of the path to all UseTreeList items.
|
/// appending the rest of the path to all UseTreeList items.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// `prefix$0::suffix` -> `prefix::{suffix}`
|
||||||
|
///
|
||||||
|
/// `prefix$0` -> `prefix::{self}`
|
||||||
|
///
|
||||||
|
/// `prefix$0::*` -> `prefix::{*}`
|
||||||
pub fn split_prefix(&self, prefix: &ast::Path) {
|
pub fn split_prefix(&self, prefix: &ast::Path) {
|
||||||
debug_assert_eq!(self.path(), Some(prefix.top_path()));
|
debug_assert_eq!(self.path(), Some(prefix.top_path()));
|
||||||
let path = self.path().unwrap();
|
let path = self.path().unwrap();
|
||||||
if &path == prefix && self.use_tree_list().is_none() {
|
if &path == prefix && self.use_tree_list().is_none() {
|
||||||
let self_suffix = make::path_unqualified(make::path_segment_self()).clone_for_update();
|
if self.star_token().is_some() {
|
||||||
ted::replace(path.syntax(), self_suffix.syntax());
|
// path$0::* -> *
|
||||||
|
self.coloncolon_token().map(ted::remove);
|
||||||
|
ted::remove(prefix.syntax());
|
||||||
|
} else {
|
||||||
|
// path$0 -> self
|
||||||
|
let self_suffix =
|
||||||
|
make::path_unqualified(make::path_segment_self()).clone_for_update();
|
||||||
|
ted::replace(path.syntax(), self_suffix.syntax());
|
||||||
|
}
|
||||||
} else if split_path_prefix(prefix).is_none() {
|
} else if split_path_prefix(prefix).is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// At this point, prefix path is detached; _self_ use tree has suffix path.
|
||||||
|
// Next, transoform 'suffix' use tree into 'prefix::{suffix}'
|
||||||
let subtree = self.clone_subtree().clone_for_update();
|
let subtree = self.clone_subtree().clone_for_update();
|
||||||
ted::remove_all_iter(self.syntax().children_with_tokens());
|
ted::remove_all_iter(self.syntax().children_with_tokens());
|
||||||
ted::insert(Position::first_child_of(self.syntax()), prefix.syntax());
|
ted::insert(Position::first_child_of(self.syntax()), prefix.syntax());
|
||||||
|
Loading…
Reference in New Issue
Block a user