Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/completions/trait_impl.rs')
-rw-r--r--crates/ide-completion/src/completions/trait_impl.rs108
1 files changed, 91 insertions, 17 deletions
diff --git a/crates/ide-completion/src/completions/trait_impl.rs b/crates/ide-completion/src/completions/trait_impl.rs
index 61c5d12649..54bd77526e 100644
--- a/crates/ide-completion/src/completions/trait_impl.rs
+++ b/crates/ide-completion/src/completions/trait_impl.rs
@@ -32,10 +32,12 @@
//! ```
use hir::{self, HasAttrs};
-use ide_db::{path_transform::PathTransform, traits::get_missing_assoc_items, SymbolKind};
+use ide_db::{
+ path_transform::PathTransform, syntax_helpers::insert_whitespace_into_node,
+ traits::get_missing_assoc_items, SymbolKind,
+};
use syntax::{
ast::{self, edit_in_place::AttrsOwnerEdit},
- display::function_declaration,
AstNode, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, T,
};
use text_edit::TextEdit;
@@ -179,7 +181,7 @@ fn add_function_impl(
_ => unreachable!(),
};
- let function_decl = function_declaration(&transformed_fn);
+ let function_decl = function_declaration(&transformed_fn, source.file_id.is_macro());
match ctx.config.snippet_cap {
Some(cap) => {
let snippet = format!("{} {{\n $0\n}}", function_decl);
@@ -260,7 +262,7 @@ fn add_const_impl(
_ => unreachable!(),
};
- let label = make_const_compl_syntax(&transformed_const);
+ let label = make_const_compl_syntax(&transformed_const, source.file_id.is_macro());
let replacement = format!("{} ", label);
let mut item = CompletionItem::new(SymbolKind::Const, replacement_range, label);
@@ -283,17 +285,18 @@ fn add_const_impl(
}
}
-fn make_const_compl_syntax(const_: &ast::Const) -> String {
+fn make_const_compl_syntax(const_: &ast::Const, needs_whitespace: bool) -> String {
const_.remove_attrs_and_docs();
+ let const_ = if needs_whitespace {
+ insert_whitespace_into_node::insert_ws_into(const_.syntax().clone())
+ } else {
+ const_.syntax().clone()
+ };
- let const_start = const_.syntax().text_range().start();
- let const_end = const_.syntax().text_range().end();
-
- let start =
- const_.syntax().first_child_or_token().map_or(const_start, |f| f.text_range().start());
+ let start = const_.text_range().start();
+ let const_end = const_.text_range().end();
let end = const_
- .syntax()
.children_with_tokens()
.find(|s| s.kind() == T![;] || s.kind() == T![=])
.map_or(const_end, |f| f.text_range().start());
@@ -301,11 +304,36 @@ fn make_const_compl_syntax(const_: &ast::Const) -> String {
let len = end - start;
let range = TextRange::new(0.into(), len);
- let syntax = const_.syntax().text().slice(range).to_string();
+ let syntax = const_.text().slice(range).to_string();
format!("{} =", syntax.trim_end())
}
+fn function_declaration(node: &ast::Fn, needs_whitespace: bool) -> String {
+ node.remove_attrs_and_docs();
+
+ let node = if needs_whitespace {
+ insert_whitespace_into_node::insert_ws_into(node.syntax().clone())
+ } else {
+ node.syntax().clone()
+ };
+
+ let start = node.text_range().start();
+ let end = node.text_range().end();
+
+ let end = node
+ .last_child_or_token()
+ .filter(|s| s.kind() == T![;] || s.kind() == SyntaxKind::BLOCK_EXPR)
+ .map_or(end, |f| f.text_range().start());
+
+ let len = end - start;
+ let range = TextRange::new(0.into(), len);
+
+ let syntax = node.text().slice(range).to_string();
+
+ syntax.trim_end().to_owned()
+}
+
fn replacement_range(ctx: &CompletionContext, item: &SyntaxNode) -> TextRange {
let first_child = item
.children_with_tokens()
@@ -655,8 +683,7 @@ trait Test {
struct T;
impl Test for T {
- fn foo<T>()
-where T: Into<String> {
+ fn foo<T>() where T: Into<String> {
$0
}
}
@@ -992,7 +1019,7 @@ trait SomeTrait<T> {}
trait Foo<T> {
fn function()
- where Self: SomeTrait<T>;
+ where Self: SomeTrait<T>;
}
struct Bar;
@@ -1005,13 +1032,13 @@ 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
}
}
@@ -1052,4 +1079,51 @@ impl Tr for () {
"#]],
);
}
+
+ #[test]
+ fn fixes_up_macro_generated() {
+ check_edit(
+ "fn foo",
+ r#"
+macro_rules! noop {
+ ($($item: item)*) => {
+ $($item)*
+ }
+}
+
+noop! {
+ trait Foo {
+ fn foo(&mut self, bar: i64, baz: &mut u32) -> Result<(), u32>;
+ }
+}
+
+struct Test;
+
+impl Foo for Test {
+ $0
+}
+"#,
+ r#"
+macro_rules! noop {
+ ($($item: item)*) => {
+ $($item)*
+ }
+}
+
+noop! {
+ trait Foo {
+ fn foo(&mut self, bar: i64, baz: &mut u32) -> Result<(), u32>;
+ }
+}
+
+struct Test;
+
+impl Foo for Test {
+ fn foo(&mut self,bar:i64,baz: &mut u32) -> Result<(),u32> {
+ $0
+}
+}
+"#,
+ );
+ }
}