Skip to content

Commit 4295a00

Browse files
Operate only on AST paths instead of HIR
1 parent aaaa68b commit 4295a00

File tree

1 file changed

+36
-30
lines changed

1 file changed

+36
-30
lines changed

crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use hir::{self, ModPath};
1+
use hir;
22
use ra_syntax::{algo::SyntaxRewriter, ast, match_ast, AstNode, SmolStr, SyntaxNode};
33

44
use crate::{
@@ -50,13 +50,9 @@ pub(crate) fn replace_qualified_name_with_use(
5050

5151
// Now that we've brought the name into scope, re-qualify all paths that could be
5252
// affected (that is, all paths inside the node we added the `use` to).
53-
let hir_path = match hir::Path::from_ast(path.clone()) {
54-
Some(p) => p,
55-
None => return,
56-
};
5753
let mut rewriter = SyntaxRewriter::default();
5854
let syntax = container.either(|l| l.syntax().clone(), |r| r.syntax().clone());
59-
shorten_paths(&mut rewriter, syntax, hir_path.mod_path());
55+
shorten_paths(&mut rewriter, syntax, path);
6056
builder.rewrite(rewriter);
6157
},
6258
)
@@ -83,7 +79,7 @@ fn collect_hir_path_segments(path: &hir::Path) -> Option<Vec<SmolStr>> {
8379
}
8480

8581
/// Adds replacements to `re` that shorten `path` in all descendants of `node`.
86-
fn shorten_paths(rewriter: &mut SyntaxRewriter<'static>, node: SyntaxNode, path: &ModPath) {
82+
fn shorten_paths(rewriter: &mut SyntaxRewriter<'static>, node: SyntaxNode, path: ast::Path) {
8783
for child in node.children() {
8884
match_ast! {
8985
match child {
@@ -94,47 +90,57 @@ fn shorten_paths(rewriter: &mut SyntaxRewriter<'static>, node: SyntaxNode, path:
9490
ast::Module(_it) => continue,
9591

9692
ast::Path(p) => {
97-
match maybe_replace_path(rewriter, &p, path) {
93+
match maybe_replace_path(rewriter, p.clone(), path.clone()) {
9894
Some(()) => {},
99-
None => shorten_paths(rewriter, p.syntax().clone(), path),
95+
None => shorten_paths(rewriter, p.syntax().clone(), path.clone()),
10096
}
10197
},
102-
_ => shorten_paths(rewriter, child, path),
98+
_ => shorten_paths(rewriter, child, path.clone()),
10399
}
104100
}
105101
}
106102
}
107103

108104
fn maybe_replace_path(
109-
re: &mut SyntaxRewriter<'static>,
110-
p: &ast::Path,
111-
path: &ModPath,
105+
rewriter: &mut SyntaxRewriter<'static>,
106+
path: ast::Path,
107+
target: ast::Path,
112108
) -> Option<()> {
113-
let hir_path = hir::Path::from_ast(p.clone())?;
114-
115-
if hir_path.mod_path() != path {
109+
if !path_eq(path.clone(), target.clone()) {
116110
return None;
117111
}
118112

119-
// Replace path with its last "plain" segment.
120-
let mut mod_path = hir_path.mod_path().clone();
121-
let last = mod_path.segments.len() - 1;
122-
mod_path.segments.swap(0, last);
123-
mod_path.segments.truncate(1);
124-
mod_path.kind = hir::PathKind::Plain;
125-
126-
let mut new_path = crate::ast_transform::path_to_ast(mod_path);
127-
128-
let type_args = p.segment().and_then(|s| s.type_arg_list());
129-
if let Some(type_args) = type_args {
130-
let last_segment = new_path.segment().unwrap();
131-
new_path = new_path.with_segment(last_segment.with_type_args(type_args));
113+
// Shorten `path`, leaving only its last segment.
114+
if let Some(parent) = path.qualifier() {
115+
rewriter.delete(parent.syntax());
116+
}
117+
if let Some(double_colon) = path.coloncolon_token() {
118+
rewriter.delete(&double_colon);
132119
}
133120

134-
re.replace(p.syntax(), new_path.syntax());
135121
Some(())
136122
}
137123

124+
fn path_eq(lhs: ast::Path, rhs: ast::Path) -> bool {
125+
let mut lhs_curr = lhs;
126+
let mut rhs_curr = rhs;
127+
loop {
128+
match (lhs_curr.segment(), rhs_curr.segment()) {
129+
(Some(lhs), Some(rhs)) if lhs.syntax().text() == rhs.syntax().text() => (),
130+
_ => return false,
131+
}
132+
133+
match (lhs_curr.qualifier(), rhs_curr.qualifier()) {
134+
(Some(lhs), Some(rhs)) => {
135+
lhs_curr = lhs;
136+
rhs_curr = rhs;
137+
}
138+
(None, None) => return true,
139+
_ => return false,
140+
}
141+
}
142+
}
143+
138144
#[cfg(test)]
139145
mod tests {
140146
use crate::tests::{check_assist, check_assist_not_applicable};

0 commit comments

Comments
 (0)