Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/qualify_path.rs')
-rw-r--r--crates/ide-assists/src/handlers/qualify_path.rs45
1 files changed, 29 insertions, 16 deletions
diff --git a/crates/ide-assists/src/handlers/qualify_path.rs b/crates/ide-assists/src/handlers/qualify_path.rs
index b3cf296965..c059f758c4 100644
--- a/crates/ide-assists/src/handlers/qualify_path.rs
+++ b/crates/ide-assists/src/handlers/qualify_path.rs
@@ -11,7 +11,8 @@ use syntax::Edition;
use syntax::ast::HasGenericArgs;
use syntax::{
AstNode, ast,
- ast::{HasArgList, make},
+ ast::{HasArgList, syntax_factory::SyntaxFactory},
+ syntax_editor::SyntaxEditor,
};
use crate::{
@@ -54,25 +55,25 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
let qualify_candidate = match candidate {
ImportCandidate::Path(candidate) if !candidate.qualifier.is_empty() => {
cov_mark::hit!(qualify_path_qualifier_start);
- let path = ast::Path::cast(syntax_under_caret)?;
+ let path = ast::Path::cast(syntax_under_caret.clone())?;
let (prev_segment, segment) = (path.qualifier()?.segment()?, path.segment()?);
QualifyCandidate::QualifierStart(segment, prev_segment.generic_arg_list())
}
ImportCandidate::Path(_) => {
cov_mark::hit!(qualify_path_unqualified_name);
- let path = ast::Path::cast(syntax_under_caret)?;
+ let path = ast::Path::cast(syntax_under_caret.clone())?;
let generics = path.segment()?.generic_arg_list();
QualifyCandidate::UnqualifiedName(generics)
}
ImportCandidate::TraitAssocItem(_) => {
cov_mark::hit!(qualify_path_trait_assoc_item);
- let path = ast::Path::cast(syntax_under_caret)?;
+ let path = ast::Path::cast(syntax_under_caret.clone())?;
let (qualifier, segment) = (path.qualifier()?, path.segment()?);
QualifyCandidate::TraitAssocItem(qualifier, segment)
}
ImportCandidate::TraitMethod(_) => {
cov_mark::hit!(qualify_path_trait_method);
- let mcall_expr = ast::MethodCallExpr::cast(syntax_under_caret)?;
+ let mcall_expr = ast::MethodCallExpr::cast(syntax_under_caret.clone())?;
QualifyCandidate::TraitMethod(ctx.sema.db, mcall_expr)
}
};
@@ -101,12 +102,18 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
label(ctx.db(), candidate, &import, current_edition),
range,
|builder| {
+ let make = SyntaxFactory::with_mappings();
+ let mut editor = builder.make_editor(&syntax_under_caret);
qualify_candidate.qualify(
|replace_with: String| builder.replace(range, replace_with),
+ &mut editor,
+ &make,
&import.import_path,
import.item_to_import,
current_edition,
- )
+ );
+ editor.add_mappings(make.finish_with_mappings());
+ builder.add_file_edits(ctx.vfs_file_id(), editor);
},
);
}
@@ -124,6 +131,8 @@ impl QualifyCandidate<'_> {
pub(crate) fn qualify(
&self,
mut replacer: impl FnMut(String),
+ editor: &mut SyntaxEditor,
+ make: &SyntaxFactory,
import: &hir::ModPath,
item: hir::ItemInNs,
edition: Edition,
@@ -142,10 +151,10 @@ impl QualifyCandidate<'_> {
replacer(format!("<{qualifier} as {import}>::{segment}"));
}
QualifyCandidate::TraitMethod(db, mcall_expr) => {
- Self::qualify_trait_method(db, mcall_expr, replacer, import, item);
+ Self::qualify_trait_method(db, mcall_expr, editor, make, import, item);
}
QualifyCandidate::ImplMethod(db, mcall_expr, hir_fn) => {
- Self::qualify_fn_call(db, mcall_expr, replacer, import, hir_fn);
+ Self::qualify_fn_call(db, mcall_expr, editor, make, import, hir_fn);
}
}
}
@@ -153,7 +162,8 @@ impl QualifyCandidate<'_> {
fn qualify_fn_call(
db: &RootDatabase,
mcall_expr: &ast::MethodCallExpr,
- mut replacer: impl FnMut(String),
+ editor: &mut SyntaxEditor,
+ make: &SyntaxFactory,
import: ast::Path,
hir_fn: &hir::Function,
) -> Option<()> {
@@ -165,15 +175,17 @@ impl QualifyCandidate<'_> {
if let Some(self_access) = hir_fn.self_param(db).map(|sp| sp.access(db)) {
let receiver = match self_access {
- hir::Access::Shared => make::expr_ref(receiver, false),
- hir::Access::Exclusive => make::expr_ref(receiver, true),
+ hir::Access::Shared => make.expr_ref(receiver, false),
+ hir::Access::Exclusive => make.expr_ref(receiver, true),
hir::Access::Owned => receiver,
};
let arg_list = match arg_list {
- Some(args) => make::arg_list(iter::once(receiver).chain(args)),
- None => make::arg_list(iter::once(receiver)),
+ Some(args) => make.arg_list(iter::once(receiver).chain(args)),
+ None => make.arg_list(iter::once(receiver)),
};
- replacer(format!("{import}::{method_name}{generics}{arg_list}"));
+ let call_path = make.path_from_text(&format!("{import}::{method_name}{generics}"));
+ let call_expr = make.expr_call(make.expr_path(call_path), arg_list);
+ editor.replace(mcall_expr.syntax(), call_expr.syntax());
}
Some(())
}
@@ -181,14 +193,15 @@ impl QualifyCandidate<'_> {
fn qualify_trait_method(
db: &RootDatabase,
mcall_expr: &ast::MethodCallExpr,
- replacer: impl FnMut(String),
+ editor: &mut SyntaxEditor,
+ make: &SyntaxFactory,
import: ast::Path,
item: hir::ItemInNs,
) -> Option<()> {
let trait_method_name = mcall_expr.name_ref()?;
let trait_ = item_as_trait(db, item)?;
let method = find_trait_method(db, trait_, &trait_method_name)?;
- Self::qualify_fn_call(db, mcall_expr, replacer, import, &method)
+ Self::qualify_fn_call(db, mcall_expr, editor, make, import, &method)
}
}