//! }
//!
//! impl SomeTrait for () {
-//! fn f<|>
+//! fn f$0
//! }
//! ```
//!
//! # }
//!
//! impl SomeTrait for () {
-//! fn foo() {}<|>
+//! fn foo() {}$0
//! }
//! ```
fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, SyntaxNode, Impl)> {
let mut token = ctx.token.clone();
- // For keywork without name like `impl .. { fn <|> }`, the current position is inside
+ // For keywork without name like `impl .. { fn $0 }`, the current position is inside
// the whitespace token, which is outside `FN` syntax node.
// We need to follow the previous token in this case.
if token.kind() == SyntaxKind::WHITESPACE {
}
let impl_item_offset = match token.kind() {
- // `impl .. { const <|> }`
+ // `impl .. { const $0 }`
// ERROR 0
// CONST_KW <- *
- SyntaxKind::CONST_KW => 0,
- // `impl .. { fn/type <|> }`
+ T![const] => 0,
+ // `impl .. { fn/type $0 }`
// FN/TYPE_ALIAS 0
// FN_KW <- *
- SyntaxKind::FN_KW | SyntaxKind::TYPE_KW => 0,
- // `impl .. { fn/type/const foo<|> }`
+ T![fn] | T![type] => 0,
+ // `impl .. { fn/type/const foo$0 }`
// FN/TYPE_ALIAS/CONST 1
// NAME 0
// IDENT <- *
SyntaxKind::IDENT if token.parent().kind() == SyntaxKind::NAME => 1,
- // `impl .. { foo<|> }`
+ // `impl .. { foo$0 }`
// MACRO_CALL 3
// PATH 2
// PATH_SEGMENT 1
// <item>
let impl_def = ast::Impl::cast(impl_item.parent()?.parent()?)?;
let kind = match impl_item.kind() {
- // `impl ... { const <|> fn/type/const }`
- _ if token.kind() == SyntaxKind::CONST_KW => ImplCompletionKind::Const,
+ // `impl ... { const $0 fn/type/const }`
+ _ if token.kind() == T![const] => ImplCompletionKind::Const,
SyntaxKind::CONST | SyntaxKind::ERROR => ImplCompletionKind::Const,
SyntaxKind::TYPE_ALIAS => ImplCompletionKind::TypeAlias,
SyntaxKind::FN => ImplCompletionKind::Fn,
struct T;
impl Test for T {
- t<|>
+ t$0
}
"#,
expect![["
impl Test for T {
fn test() {
- t<|>
+ t$0
}
}
",
impl Test for T {
fn test() {
- fn t<|>
+ fn t$0
}
}
",
impl Test for T {
fn test() {
- fn <|>
+ fn $0
}
}
",
impl Test for T {
fn test() {
- foo.<|>
+ foo.$0
}
}
",
struct T;
impl Test for T {
- fn test(t<|>)
+ fn test(t$0)
}
",
expect![[""]],
struct T;
impl Test for T {
- fn test(f: fn <|>)
+ fn test(f: fn $0)
}
",
expect![[""]],
struct T;
impl Test for T {
- const TEST: fn <|>
+ const TEST: fn $0
}
",
expect![[""]],
struct T;
impl Test for T {
- const TEST: T<|>
+ const TEST: T$0
}
",
expect![[""]],
struct T;
impl Test for T {
- const TEST: u32 = f<|>
+ const TEST: u32 = f$0
}
",
expect![[""]],
impl Test for T {
const TEST: u32 = {
- t<|>
+ t$0
};
}
",
impl Test for T {
const TEST: u32 = {
- fn <|>
+ fn $0
};
}
",
impl Test for T {
const TEST: u32 = {
- fn t<|>
+ fn t$0
};
}
",
struct T;
impl Test for T {
- type Test = T<|>;
+ type Test = T$0;
}
",
expect![[""]],
struct T;
impl Test for T {
- type Test = fn <|>;
+ type Test = fn $0;
}
",
expect![[""]],
struct T;
impl Test for T {
- t<|>
+ t$0
}
"#,
r#"
struct T;
impl Test for T {
- fn t<|>
+ fn t$0
}
"#,
r#"
impl Test for T {
fn foo() {}
- fn f<|>
+ fn f$0
}
"#,
expect![[r#"
struct T;
impl Test for T {
- fn f<|>
+ fn f$0
}
"#,
r#"
struct T;
impl Test for T {
- fn f<|>
+ fn f$0
}
"#,
r#"
}
impl Test for () {
- type S<|>
+ type S$0
}
"#,
"
}
impl Test for () {
- const S<|>
+ const S$0
}
"#,
"
}
impl Test for () {
- const S<|>
+ const S$0
}
"#,
"
// Enumerate some possible next siblings.
for next_sibling in &[
"",
- "fn other_fn() {}", // `const <|> fn` -> `const fn`
+ "fn other_fn() {}", // `const $0 fn` -> `const fn`
"type OtherType = i32;",
"const OTHER_CONST: i32 = 0;",
"async fn other_fn() {}",
"default type OtherType = i32;",
"default const OTHER_CONST: i32 = 0;",
] {
- test("bar", "fn <|>", "fn bar() {\n $0\n}", next_sibling);
- test("Foo", "type <|>", "type Foo = ", next_sibling);
- test("CONST", "const <|>", "const CONST: u16 = ", next_sibling);
+ test("bar", "fn $0", "fn bar() {\n $0\n}", next_sibling);
+ test("Foo", "type $0", "type Foo = ", next_sibling);
+ test("CONST", "const $0", "const CONST: u16 = ", next_sibling);
}
}
}