Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/completions/item_list/trait_impl.rs')
-rw-r--r--crates/ide-completion/src/completions/item_list/trait_impl.rs122
1 files changed, 63 insertions, 59 deletions
diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs
index 4072f05a41..c165a32082 100644
--- a/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -38,10 +38,14 @@ use ide_db::{
syntax_helpers::prettify_macro_expansion, traits::get_missing_assoc_items,
};
use syntax::ast::HasGenericParams;
+use syntax::syntax_editor::{Position, SyntaxEditor};
use syntax::{
AstNode, SmolStr, SyntaxElement, SyntaxKind, T, TextRange, ToSmolStr,
- ast::{self, HasGenericArgs, HasTypeBounds, edit_in_place::AttrsOwnerEdit, make},
- format_smolstr, ted,
+ ast::{
+ self, HasGenericArgs, HasTypeBounds,
+ edit::{AstNodeEdit, AttrsOwnerEdit},
+ },
+ format_smolstr,
};
use crate::{
@@ -59,7 +63,7 @@ enum ImplCompletionKind {
pub(crate) fn complete_trait_impl_const(
acc: &mut Completions,
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
name: &Option<ast::Name>,
) -> Option<()> {
complete_trait_impl_name(acc, ctx, name, ImplCompletionKind::Const)
@@ -67,7 +71,7 @@ pub(crate) fn complete_trait_impl_const(
pub(crate) fn complete_trait_impl_type_alias(
acc: &mut Completions,
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
name: &Option<ast::Name>,
) -> Option<()> {
complete_trait_impl_name(acc, ctx, name, ImplCompletionKind::TypeAlias)
@@ -75,7 +79,7 @@ pub(crate) fn complete_trait_impl_type_alias(
pub(crate) fn complete_trait_impl_fn(
acc: &mut Completions,
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
name: &Option<ast::Name>,
) -> Option<()> {
complete_trait_impl_name(acc, ctx, name, ImplCompletionKind::Fn)
@@ -83,7 +87,7 @@ pub(crate) fn complete_trait_impl_fn(
fn complete_trait_impl_name(
acc: &mut Completions,
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
name: &Option<ast::Name>,
kind: ImplCompletionKind,
) -> Option<()> {
@@ -122,7 +126,7 @@ fn complete_trait_impl_name(
pub(crate) fn complete_trait_impl_item_by_name(
acc: &mut Completions,
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
path_ctx: &PathCompletionCtx<'_>,
name_ref: &Option<ast::NameRef>,
impl_: &Option<ast::Impl>,
@@ -149,7 +153,7 @@ pub(crate) fn complete_trait_impl_item_by_name(
fn complete_trait_impl(
acc: &mut Completions,
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
kind: ImplCompletionKind,
replacement_range: TextRange,
impl_def: &ast::Impl,
@@ -178,7 +182,7 @@ fn complete_trait_impl(
fn add_function_impl(
acc: &mut Completions,
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
replacement_range: TextRange,
func: hir::Function,
impl_def: hir::Impl,
@@ -198,7 +202,7 @@ fn add_function_impl(
fn add_function_impl_(
acc: &mut Completions,
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
replacement_range: TextRange,
func: hir::Function,
impl_def: hir::Impl,
@@ -233,13 +237,14 @@ fn add_function_impl_(
get_transformed_fn(ctx, source.value, impl_def, async_sugaring)
{
let function_decl = function_declaration(ctx, &transformed_fn, source.file_id.macro_file());
+ let ws = if function_decl.contains('\n') { "\n" } else { " " };
match ctx.config.snippet_cap {
Some(cap) => {
- let snippet = format!("{function_decl} {{\n $0\n}}");
+ let snippet = format!("{function_decl}{ws}{{\n $0\n}}");
item.snippet_edit(cap, TextEdit::replace(replacement_range, snippet));
}
None => {
- let header = format!("{function_decl} {{");
+ let header = format!("{function_decl}{ws}{{");
item.text_edit(TextEdit::replace(replacement_range, header));
}
};
@@ -257,70 +262,65 @@ enum AsyncSugaring {
/// Transform a relevant associated item to inline generics from the impl, remove attrs and docs, etc.
fn get_transformed_assoc_item(
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
assoc_item: ast::AssocItem,
impl_def: hir::Impl,
) -> Option<ast::AssocItem> {
let trait_ = impl_def.trait_(ctx.db)?;
let source_scope = &ctx.sema.scope(assoc_item.syntax())?;
- let target_scope = &ctx.sema.scope(ctx.sema.source(impl_def)?.syntax().value)?;
- let transform = PathTransform::trait_impl(
- target_scope,
- source_scope,
- trait_,
- ctx.sema.source(impl_def)?.value,
- );
+ let impl_source = ctx.sema.source(impl_def)?;
+ let target_scope = &ctx.sema.scope(impl_source.syntax().value)?;
+ let transform =
+ PathTransform::trait_impl(target_scope, source_scope, trait_, impl_source.value);
- let assoc_item = assoc_item.clone_for_update();
// FIXME: Paths in nested macros are not handled well. See
// `macro_generated_assoc_item2` test.
let assoc_item = ast::AssocItem::cast(transform.apply(assoc_item.syntax()))?;
- assoc_item.remove_attrs_and_docs();
- Some(assoc_item)
+ let (editor, assoc_item) = SyntaxEditor::with_ast_node(&assoc_item);
+ assoc_item.remove_attrs_and_docs(&editor);
+ ast::AssocItem::cast(editor.finish().new_root().clone())
}
/// Transform a relevant associated item to inline generics from the impl, remove attrs and docs, etc.
fn get_transformed_fn(
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
fn_: ast::Fn,
impl_def: hir::Impl,
async_: AsyncSugaring,
) -> Option<ast::Fn> {
let trait_ = impl_def.trait_(ctx.db)?;
let source_scope = &ctx.sema.scope(fn_.syntax())?;
- let target_scope = &ctx.sema.scope(ctx.sema.source(impl_def)?.syntax().value)?;
- let transform = PathTransform::trait_impl(
- target_scope,
- source_scope,
- trait_,
- ctx.sema.source(impl_def)?.value,
- );
+ let impl_source = ctx.sema.source(impl_def)?;
+ let target_scope = &ctx.sema.scope(impl_source.syntax().value)?;
+ let transform =
+ PathTransform::trait_impl(target_scope, source_scope, trait_, impl_source.value);
- let fn_ = fn_.clone_for_update();
+ let fn_ = fn_.reset_indent();
// FIXME: Paths in nested macros are not handled well. See
// `macro_generated_assoc_item2` test.
let fn_ = ast::Fn::cast(transform.apply(fn_.syntax()))?;
- fn_.remove_attrs_and_docs();
+ let (editor, fn_) = SyntaxEditor::with_ast_node(&fn_);
+ let factory = editor.make();
+ fn_.remove_attrs_and_docs(&editor);
match async_ {
AsyncSugaring::Desugar => {
match fn_.ret_type() {
Some(ret_ty) => {
let ty = ret_ty.ty()?;
- ted::replace(
+ editor.replace(
ty.syntax(),
- make::ty(&format!("impl Future<Output = {ty}>"))
- .syntax()
- .clone_for_update(),
+ factory.ty(&format!("impl Future<Output = {ty}>")).syntax(),
+ );
+ }
+ None => {
+ let ret_type = factory.ret_type(factory.ty("impl Future<Output = ()>"));
+ editor.insert_with_whitespace(
+ Position::after(fn_.param_list()?.syntax()),
+ ret_type.syntax(),
);
}
- None => ted::append_child(
- fn_.param_list()?.syntax(),
- make::ret_type(make::ty("impl Future<Output = ()>"))
- .syntax()
- .clone_for_update(),
- ),
}
- fn_.async_token().unwrap().detach();
+ editor.delete(fn_.async_token()?);
}
AsyncSugaring::Resugar => {
let ty = fn_.ret_type()?.ty()?;
@@ -347,23 +347,26 @@ fn get_transformed_fn(
if let ast::Type::TupleType(ty) = &output
&& ty.fields().next().is_none()
{
- ted::remove(fn_.ret_type()?.syntax());
+ editor.delete(fn_.ret_type()?.syntax());
} else {
- ted::replace(ty.syntax(), output.syntax());
+ editor.replace(ty.syntax(), output.syntax());
}
}
_ => (),
}
- ted::prepend_child(fn_.syntax(), make::token(T![async]));
+ editor.insert_with_whitespace(
+ Position::first_child_of(fn_.syntax()),
+ factory.token(T![async]),
+ );
}
AsyncSugaring::Async | AsyncSugaring::Plain => (),
}
- Some(fn_)
+ ast::Fn::cast(editor.finish().new_root().clone())
}
fn add_type_alias_impl(
acc: &mut Completions,
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
replacement_range: TextRange,
type_alias: hir::TypeAlias,
impl_def: hir::Impl,
@@ -444,7 +447,7 @@ fn add_type_alias_impl(
fn add_const_impl(
acc: &mut Completions,
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
replacement_range: TextRange,
const_: hir::Const,
impl_def: hir::Impl,
@@ -486,13 +489,13 @@ fn add_const_impl(
}
fn make_const_compl_syntax(
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
const_: &ast::Const,
macro_file: Option<MacroCallId>,
) -> SmolStr {
let const_ = if let Some(macro_file) = macro_file {
let span_map = ctx.db.expansion_span_map(macro_file);
- prettify_macro_expansion(ctx.db, const_.syntax().clone(), &span_map, ctx.krate.into())
+ prettify_macro_expansion(ctx.db, const_.syntax().clone(), span_map, ctx.krate.into())
} else {
const_.syntax().clone()
};
@@ -514,13 +517,13 @@ fn make_const_compl_syntax(
}
fn function_declaration(
- ctx: &CompletionContext<'_>,
+ ctx: &CompletionContext<'_, '_>,
node: &ast::Fn,
macro_file: Option<MacroCallId>,
) -> String {
let node = if let Some(macro_file) = macro_file {
let span_map = ctx.db.expansion_span_map(macro_file);
- prettify_macro_expansion(ctx.db, node.syntax().clone(), &span_map, ctx.krate.into())
+ prettify_macro_expansion(ctx.db, node.syntax().clone(), span_map, ctx.krate.into())
} else {
node.syntax().clone()
};
@@ -1256,7 +1259,7 @@ trait SomeTrait<T> {}
trait Foo<T> {
fn function()
- where Self: SomeTrait<T>;
+ where Self: SomeTrait<T>;
}
struct Bar;
@@ -1269,13 +1272,14 @@ trait SomeTrait<T> {}
trait Foo<T> {
fn function()
- where Self: SomeTrait<T>;
+ where Self: SomeTrait<T>;
}
struct Bar;
impl Foo<u32> for Bar {
fn function()
- where Self: SomeTrait<u32> {
+where Self: SomeTrait<u32>
+{
$0
}
}
@@ -1356,7 +1360,7 @@ noop! {
struct Test;
impl Foo for Test {
- fn foo(&mut self,bar:i64,baz: &mut u32) -> Result<(),u32> {
+ fn foo(&mut self,bar: i64,baz: &mut u32) -> Result<(),u32> {
$0
}
}
@@ -1740,7 +1744,7 @@ impl Trait for () {
me fn bar(..)
me fn baz(..)
me fn foo(..)
- md proc_macros
+ md proc_macros::
kw crate::
kw self::
"#]],