rust/crates/ra_ide/src/completion/complete_unqualified_path.rs

1426 lines
36 KiB
Rust
Raw Normal View History

2020-03-07 15:27:03 +01:00
//! Completion of names from the current scope, e.g. locals and imported items.
use hir::ScopeDef;
2020-05-20 12:59:20 +02:00
use test_utils::mark;
use crate::completion::{CompletionContext, Completions};
use hir::{Adt, ModuleDef, Type};
use ra_syntax::AstNode;
2019-01-08 22:33:36 +03:00
2020-04-07 13:20:41 +02:00
pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
2020-05-04 16:48:50 +02:00
if !(ctx.is_trivial_path || ctx.is_pat_binding_or_const) {
return;
}
if ctx.record_lit_syntax.is_some()
|| ctx.record_pat_syntax.is_some()
2020-05-04 16:48:50 +02:00
|| ctx.attribute_under_caret.is_some()
{
2019-09-06 21:57:11 +03:00
return;
}
if let Some(ty) = &ctx.expected_type {
complete_enum_variants(acc, ctx, ty);
}
if ctx.is_pat_binding_or_const {
return;
}
ctx.scope().process_all_names(&mut |name, res| {
if ctx.use_item_syntax.is_some() {
if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) {
if name_ref.syntax().text() == name.to_string().as_str() {
2020-05-20 12:59:20 +02:00
mark::hit!(self_fulfilling_completion);
return;
}
}
}
acc.add_resolution(ctx, name.to_string(), &res)
});
}
fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &Type) {
if let Some(Adt::Enum(enum_data)) = ty.as_adt() {
let variants = enum_data.variants(ctx.db);
let module = if let Some(module) = ctx.scope().module() {
// Compute path from the completion site if available.
module
} else {
// Otherwise fall back to the enum's definition site.
enum_data.module(ctx.db)
};
for variant in variants {
if let Some(path) = module.find_use_path(ctx.db, ModuleDef::from(variant)) {
// Variants with trivial paths are already added by the existing completion logic,
// so we should avoid adding these twice
if path.segments.len() > 1 {
acc.add_qualified_enum_variant(ctx, variant, path);
}
}
}
}
}
2019-01-08 22:33:36 +03:00
#[cfg(test)]
mod tests {
2019-08-29 16:49:10 +03:00
use insta::assert_debug_snapshot;
2020-05-20 12:59:20 +02:00
use test_utils::mark;
2019-01-08 22:33:36 +03:00
2020-03-11 10:46:43 +01:00
use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
2020-03-11 10:46:43 +01:00
fn do_reference_completion(ra_fixture: &str) -> Vec<CompletionItem> {
do_completion(ra_fixture, CompletionKind::Reference)
2019-01-08 22:33:36 +03:00
}
#[test]
fn self_fulfilling_completion() {
2020-05-20 12:59:20 +02:00
mark::check!(self_fulfilling_completion);
assert_debug_snapshot!(
do_reference_completion(
r#"
use foo<|>
use std::collections;
"#,
),
@r###"
[
CompletionItem {
label: "collections",
2020-04-24 23:51:02 +02:00
source_range: 21..24,
delete: 21..24,
insert: "collections",
},
]
"###
);
}
#[test]
fn bind_pat_and_path_ignore_at() {
assert_debug_snapshot!(
do_reference_completion(
r"
enum Enum {
A,
B,
}
fn quux(x: Option<Enum>) {
match x {
None => (),
Some(en<|> @ Enum::A) => (),
}
}
"
),
@"[]"
);
}
#[test]
fn bind_pat_and_path_ignore_ref() {
assert_debug_snapshot!(
do_reference_completion(
r"
enum Enum {
A,
B,
}
fn quux(x: Option<Enum>) {
match x {
None => (),
Some(ref en<|>) => (),
}
}
"
),
@r###"[]"###
);
}
#[test]
fn bind_pat_and_path() {
assert_debug_snapshot!(
do_reference_completion(
r"
enum Enum {
A,
B,
}
fn quux(x: Option<Enum>) {
match x {
None => (),
Some(En<|>) => (),
}
}
"
),
@r###"
[
CompletionItem {
label: "Enum",
2020-04-24 23:51:02 +02:00
source_range: 231..233,
delete: 231..233,
insert: "Enum",
kind: Enum,
},
]
"###
);
}
2019-01-08 22:33:36 +03:00
#[test]
fn completes_bindings_from_let() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(
r"
fn quux(x: i32) {
let y = 92;
1 + <|>;
let z = ();
}
"
),
@r###"
[
CompletionItem {
label: "quux(…)",
2020-04-24 23:51:02 +02:00
source_range: 91..91,
delete: 91..91,
insert: "quux(${1:x})$0",
kind: Function,
lookup: "quux",
detail: "fn quux(x: i32)",
2020-03-12 19:02:55 +01:00
trigger_call_info: true,
},
CompletionItem {
label: "x",
2020-04-24 23:51:02 +02:00
source_range: 91..91,
delete: 91..91,
insert: "x",
kind: Binding,
detail: "i32",
},
CompletionItem {
label: "y",
2020-04-24 23:51:02 +02:00
source_range: 91..91,
delete: 91..91,
insert: "y",
kind: Binding,
detail: "i32",
},
]
"###
);
2019-01-08 22:33:36 +03:00
}
#[test]
fn completes_bindings_from_if_let() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(
r"
fn quux() {
if let Some(x) = foo() {
let y = 92;
};
if let Some(a) = bar() {
let b = 62;
1 + <|>
}
2019-01-08 22:33:36 +03:00
}
"
),
@r###"
[
CompletionItem {
label: "a",
2020-04-24 23:51:02 +02:00
source_range: 242..242,
delete: 242..242,
insert: "a",
kind: Binding,
},
CompletionItem {
label: "b",
2020-04-24 23:51:02 +02:00
source_range: 242..242,
delete: 242..242,
insert: "b",
kind: Binding,
detail: "i32",
},
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "quux()",
2020-04-24 23:51:02 +02:00
source_range: 242..242,
delete: 242..242,
insert: "quux()$0",
kind: Function,
lookup: "quux",
detail: "fn quux()",
},
]
"###
);
2019-01-08 22:33:36 +03:00
}
#[test]
fn completes_bindings_from_for() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(
r"
fn quux() {
for x in &[1, 2, 3] {
<|>
}
2019-01-08 22:33:36 +03:00
}
"
),
@r###"
[
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "quux()",
2020-04-24 23:51:02 +02:00
source_range: 95..95,
delete: 95..95,
insert: "quux()$0",
kind: Function,
lookup: "quux",
detail: "fn quux()",
},
CompletionItem {
label: "x",
2020-04-24 23:51:02 +02:00
source_range: 95..95,
delete: 95..95,
insert: "x",
kind: Binding,
},
]
"###
);
2019-01-08 22:33:36 +03:00
}
#[test]
fn completes_bindings_from_for_with_in_prefix() {
mark::check!(completes_bindings_from_for_with_in_prefix);
assert_debug_snapshot!(
do_reference_completion(
r"
fn test() {
for index in &[1, 2, 3] {
let t = in<|>
}
}
"
),
@r###"
[
CompletionItem {
label: "index",
source_range: 107..107,
delete: 107..107,
insert: "index",
kind: Binding,
},
CompletionItem {
label: "test()",
source_range: 107..107,
delete: 107..107,
insert: "test()$0",
kind: Function,
lookup: "test",
detail: "fn test()",
},
]
"###
);
}
2019-02-01 23:06:57 +01:00
#[test]
fn completes_generic_params() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(
r"
fn quux<T>() {
<|>
}
"
),
@r###"
[
CompletionItem {
label: "T",
2020-04-24 23:51:02 +02:00
source_range: 52..52,
delete: 52..52,
insert: "T",
kind: TypeParam,
},
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "quux()",
2020-04-24 23:51:02 +02:00
source_range: 52..52,
delete: 52..52,
insert: "quux()$0",
kind: Function,
lookup: "quux",
detail: "fn quux<T>()",
},
]
"###
);
2019-02-01 23:06:57 +01:00
}
#[test]
fn completes_generic_params_in_struct() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(
r"
struct X<T> {
x: <|>
}
"
),
2019-10-08 21:14:52 +03:00
@r###"
[
2019-11-20 21:55:33 +03:00
CompletionItem {
label: "Self",
2020-04-24 23:51:02 +02:00
source_range: 54..54,
delete: 54..54,
2019-11-20 21:55:33 +03:00
insert: "Self",
kind: TypeParam,
},
2019-10-08 21:14:52 +03:00
CompletionItem {
label: "T",
2020-04-24 23:51:02 +02:00
source_range: 54..54,
delete: 54..54,
2019-10-08 21:14:52 +03:00
insert: "T",
kind: TypeParam,
},
CompletionItem {
label: "X<…>",
2020-04-24 23:51:02 +02:00
source_range: 54..54,
delete: 54..54,
2019-10-08 21:14:52 +03:00
insert: "X<$0>",
kind: Struct,
lookup: "X",
2019-10-08 21:14:52 +03:00
},
]
"###
);
2019-02-01 23:06:57 +01:00
}
2019-01-08 22:33:36 +03:00
#[test]
fn completes_self_in_enum() {
assert_debug_snapshot!(
do_reference_completion(
r"
enum X {
Y(<|>)
}
"
),
2019-10-08 21:14:52 +03:00
@r###"
[
CompletionItem {
label: "Self",
2020-04-24 23:51:02 +02:00
source_range: 48..48,
delete: 48..48,
2019-10-08 21:14:52 +03:00
insert: "Self",
kind: TypeParam,
},
CompletionItem {
label: "X",
2020-04-24 23:51:02 +02:00
source_range: 48..48,
delete: 48..48,
2019-10-08 21:14:52 +03:00
insert: "X",
kind: Enum,
},
]
"###
);
}
#[test]
2019-01-08 22:33:36 +03:00
fn completes_module_items() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(
r"
struct Foo;
enum Baz {}
fn quux() {
<|>
}
"
),
@r###"
[
CompletionItem {
label: "Baz",
2020-04-24 23:51:02 +02:00
source_range: 105..105,
delete: 105..105,
insert: "Baz",
kind: Enum,
},
CompletionItem {
label: "Foo",
2020-04-24 23:51:02 +02:00
source_range: 105..105,
delete: 105..105,
insert: "Foo",
kind: Struct,
},
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "quux()",
2020-04-24 23:51:02 +02:00
source_range: 105..105,
delete: 105..105,
insert: "quux()$0",
kind: Function,
lookup: "quux",
detail: "fn quux()",
},
]
"###
);
2019-01-08 22:33:36 +03:00
}
#[test]
2019-02-04 22:09:56 +01:00
fn completes_extern_prelude() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(
r"
//- /lib.rs
use <|>;
2019-02-04 22:09:56 +01:00
//- /other_crate/lib.rs
// nothing here
"
),
2019-11-15 12:56:24 +03:00
@r###"
[
CompletionItem {
label: "other_crate",
2020-04-24 23:51:02 +02:00
source_range: 4..4,
delete: 4..4,
2019-11-15 12:56:24 +03:00
insert: "other_crate",
kind: Module,
},
]
"###
);
2019-02-04 22:09:56 +01:00
}
#[test]
2019-01-08 22:33:36 +03:00
fn completes_module_items_in_nested_modules() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(
r"
struct Foo;
mod m {
struct Bar;
fn quux() { <|> }
}
"
),
@r###"
[
CompletionItem {
label: "Bar",
2020-04-24 23:51:02 +02:00
source_range: 117..117,
delete: 117..117,
insert: "Bar",
kind: Struct,
},
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "quux()",
2020-04-24 23:51:02 +02:00
source_range: 117..117,
delete: 117..117,
insert: "quux()$0",
kind: Function,
lookup: "quux",
detail: "fn quux()",
},
]
"###
);
2019-01-08 22:33:36 +03:00
}
#[test]
fn completes_return_type() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(
r"
struct Foo;
fn x() -> <|>
"
),
2019-10-08 21:14:52 +03:00
@r###"
[
CompletionItem {
label: "Foo",
2020-04-24 23:51:02 +02:00
source_range: 55..55,
delete: 55..55,
2019-10-08 21:14:52 +03:00
insert: "Foo",
kind: Struct,
},
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "x()",
2020-04-24 23:51:02 +02:00
source_range: 55..55,
delete: 55..55,
2019-10-08 21:14:52 +03:00
insert: "x()$0",
kind: Function,
lookup: "x",
2019-10-08 21:14:52 +03:00
detail: "fn x()",
},
]
"###
);
2019-01-08 22:33:36 +03:00
}
#[test]
fn dont_show_both_completions_for_shadowing() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(
r"
fn foo() {
let bar = 92;
{
let bar = 62;
<|>
}
2019-01-08 22:33:36 +03:00
}
"
),
@r###"
[
CompletionItem {
label: "bar",
2020-04-24 23:51:02 +02:00
source_range: 146..146,
delete: 146..146,
insert: "bar",
kind: Binding,
detail: "i32",
},
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "foo()",
2020-04-24 23:51:02 +02:00
source_range: 146..146,
delete: 146..146,
insert: "foo()$0",
kind: Function,
lookup: "foo",
detail: "fn foo()",
},
]
"###
);
2019-01-08 22:33:36 +03:00
}
#[test]
fn completes_self_in_methods() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(r"impl S { fn foo(&self) { <|> } }"),
2019-11-15 12:56:24 +03:00
@r###"
[
CompletionItem {
label: "Self",
2020-04-24 23:51:02 +02:00
source_range: 25..25,
delete: 25..25,
2019-11-15 12:56:24 +03:00
insert: "Self",
kind: TypeParam,
},
CompletionItem {
label: "self",
2020-04-24 23:51:02 +02:00
source_range: 25..25,
delete: 25..25,
2019-11-15 12:56:24 +03:00
insert: "self",
kind: Binding,
detail: "&{unknown}",
},
]
"###
);
2019-01-08 22:33:36 +03:00
}
2019-02-13 20:53:42 +01:00
#[test]
fn completes_prelude() {
2019-08-29 16:49:10 +03:00
assert_debug_snapshot!(
do_reference_completion(
"
//- /main.rs
fn foo() { let x: <|> }
2019-02-13 20:53:42 +01:00
//- /std/lib.rs
#[prelude_import]
use prelude::*;
2019-02-13 20:53:42 +01:00
mod prelude {
struct Option;
}
"
),
2019-10-08 21:14:52 +03:00
@r###"
[
CompletionItem {
label: "Option",
2020-04-24 23:51:02 +02:00
source_range: 18..18,
delete: 18..18,
2019-10-08 21:14:52 +03:00
insert: "Option",
kind: Struct,
},
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "foo()",
2020-04-24 23:51:02 +02:00
source_range: 18..18,
delete: 18..18,
2019-10-08 21:14:52 +03:00
insert: "foo()$0",
kind: Function,
lookup: "foo",
2019-10-08 21:14:52 +03:00
detail: "fn foo()",
},
CompletionItem {
label: "std",
2020-04-24 23:51:02 +02:00
source_range: 18..18,
delete: 18..18,
2019-10-08 21:14:52 +03:00
insert: "std",
kind: Module,
},
]
"###
);
2019-02-13 20:53:42 +01:00
}
2019-09-10 13:32:47 +08:00
#[test]
fn completes_std_prelude_if_core_is_defined() {
assert_debug_snapshot!(
do_reference_completion(
"
//- /main.rs
fn foo() { let x: <|> }
//- /core/lib.rs
#[prelude_import]
use prelude::*;
mod prelude {
struct Option;
}
//- /std/lib.rs
#[prelude_import]
use prelude::*;
mod prelude {
struct String;
}
"
),
@r###"
[
CompletionItem {
label: "String",
2020-04-24 23:51:02 +02:00
source_range: 18..18,
delete: 18..18,
insert: "String",
kind: Struct,
},
CompletionItem {
label: "core",
2020-04-24 23:51:02 +02:00
source_range: 18..18,
delete: 18..18,
insert: "core",
kind: Module,
},
CompletionItem {
label: "foo()",
2020-04-24 23:51:02 +02:00
source_range: 18..18,
delete: 18..18,
insert: "foo()$0",
kind: Function,
lookup: "foo",
detail: "fn foo()",
},
CompletionItem {
label: "std",
2020-04-24 23:51:02 +02:00
source_range: 18..18,
delete: 18..18,
insert: "std",
kind: Module,
},
]
"###
);
}
2019-09-10 13:32:47 +08:00
#[test]
fn completes_macros_as_value() {
assert_debug_snapshot!(
do_reference_completion(
"
//- /main.rs
macro_rules! foo {
() => {}
}
#[macro_use]
mod m1 {
macro_rules! bar {
() => {}
}
}
mod m2 {
macro_rules! nope {
() => {}
}
#[macro_export]
macro_rules! baz {
() => {}
}
}
fn main() {
let v = <|>
}
"
),
@r###"
[
CompletionItem {
2020-04-24 13:15:39 +02:00
label: "bar!(…)",
2020-04-24 23:51:02 +02:00
source_range: 252..252,
delete: 252..252,
insert: "bar!($0)",
kind: Macro,
detail: "macro_rules! bar",
},
CompletionItem {
2020-04-24 13:15:39 +02:00
label: "baz!(…)",
2020-04-24 23:51:02 +02:00
source_range: 252..252,
delete: 252..252,
insert: "baz!($0)",
kind: Macro,
detail: "#[macro_export]\nmacro_rules! baz",
},
CompletionItem {
2020-04-24 13:15:39 +02:00
label: "foo!(…)",
2020-04-24 23:51:02 +02:00
source_range: 252..252,
delete: 252..252,
insert: "foo!($0)",
kind: Macro,
detail: "macro_rules! foo",
},
CompletionItem {
label: "m1",
2020-04-24 23:51:02 +02:00
source_range: 252..252,
delete: 252..252,
insert: "m1",
kind: Module,
},
CompletionItem {
label: "m2",
2020-04-24 23:51:02 +02:00
source_range: 252..252,
delete: 252..252,
insert: "m2",
kind: Module,
},
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "main()",
2020-04-24 23:51:02 +02:00
source_range: 252..252,
delete: 252..252,
insert: "main()$0",
kind: Function,
lookup: "main",
detail: "fn main()",
},
]
"###
2019-09-10 13:32:47 +08:00
);
}
#[test]
fn completes_both_macro_and_value() {
assert_debug_snapshot!(
do_reference_completion(
"
//- /main.rs
macro_rules! foo {
() => {}
}
fn foo() {
<|>
}
"
),
@r###"
[
CompletionItem {
2020-04-24 13:15:39 +02:00
label: "foo!(…)",
2020-04-24 23:51:02 +02:00
source_range: 49..49,
delete: 49..49,
insert: "foo!($0)",
kind: Macro,
detail: "macro_rules! foo",
},
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "foo()",
2020-04-24 23:51:02 +02:00
source_range: 49..49,
delete: 49..49,
insert: "foo()$0",
kind: Function,
lookup: "foo",
detail: "fn foo()",
},
]
"###
2019-09-10 13:32:47 +08:00
);
}
#[test]
fn completes_macros_as_type() {
assert_debug_snapshot!(
do_reference_completion(
"
//- /main.rs
macro_rules! foo {
() => {}
}
fn main() {
let x: <|>
}
"
),
@r###"
[
CompletionItem {
2020-04-24 13:15:39 +02:00
label: "foo!(…)",
2020-04-24 23:51:02 +02:00
source_range: 57..57,
delete: 57..57,
insert: "foo!($0)",
kind: Macro,
detail: "macro_rules! foo",
},
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "main()",
2020-04-24 23:51:02 +02:00
source_range: 57..57,
delete: 57..57,
insert: "main()$0",
kind: Function,
lookup: "main",
detail: "fn main()",
},
]
"###
2019-09-10 13:32:47 +08:00
);
}
#[test]
fn completes_macros_as_stmt() {
assert_debug_snapshot!(
do_reference_completion(
"
//- /main.rs
macro_rules! foo {
() => {}
}
fn main() {
<|>
}
"
),
@r###"
[
CompletionItem {
2020-04-24 13:15:39 +02:00
label: "foo!(…)",
2020-04-24 23:51:02 +02:00
source_range: 50..50,
delete: 50..50,
insert: "foo!($0)",
kind: Macro,
detail: "macro_rules! foo",
},
CompletionItem {
2019-10-10 16:37:56 +03:00
label: "main()",
2020-04-24 23:51:02 +02:00
source_range: 50..50,
delete: 50..50,
insert: "main()$0",
kind: Function,
lookup: "main",
detail: "fn main()",
},
]
"###
2019-09-10 13:32:47 +08:00
);
}
#[test]
fn completes_local_item() {
assert_debug_snapshot!(
do_reference_completion(
"
//- /main.rs
fn main() {
return f<|>;
fn frobnicate() {}
}
"
),
@r###"
[
CompletionItem {
label: "frobnicate()",
2020-04-24 23:51:02 +02:00
source_range: 23..24,
delete: 23..24,
insert: "frobnicate()$0",
kind: Function,
lookup: "frobnicate",
detail: "fn frobnicate()",
},
CompletionItem {
label: "main()",
2020-04-24 23:51:02 +02:00
source_range: 23..24,
delete: 23..24,
insert: "main()$0",
kind: Function,
lookup: "main",
detail: "fn main()",
},
]
"###
)
}
2020-03-07 15:27:03 +01:00
#[test]
fn completes_in_simple_macro_1() {
assert_debug_snapshot!(
do_reference_completion(
r"
macro_rules! m { ($e:expr) => { $e } }
fn quux(x: i32) {
let y = 92;
m!(<|>);
}
"
),
@r###"
[
CompletionItem {
2020-04-24 13:15:39 +02:00
label: "m!(…)",
2020-04-24 23:51:02 +02:00
source_range: 145..145,
delete: 145..145,
insert: "m!($0)",
kind: Macro,
detail: "macro_rules! m",
},
CompletionItem {
label: "quux(…)",
2020-04-24 23:51:02 +02:00
source_range: 145..145,
delete: 145..145,
insert: "quux(${1:x})$0",
kind: Function,
lookup: "quux",
detail: "fn quux(x: i32)",
trigger_call_info: true,
},
CompletionItem {
label: "x",
2020-04-24 23:51:02 +02:00
source_range: 145..145,
delete: 145..145,
insert: "x",
kind: Binding,
detail: "i32",
},
CompletionItem {
label: "y",
2020-04-24 23:51:02 +02:00
source_range: 145..145,
delete: 145..145,
insert: "y",
kind: Binding,
detail: "i32",
},
]
"###
2020-03-07 15:27:03 +01:00
);
}
#[test]
fn completes_in_simple_macro_2() {
assert_debug_snapshot!(
do_reference_completion(
r"
macro_rules! m { ($e:expr) => { $e } }
fn quux(x: i32) {
let y = 92;
m!(x<|>);
}
"
),
@r###"
[
CompletionItem {
2020-04-24 13:15:39 +02:00
label: "m!(…)",
2020-04-24 23:51:02 +02:00
source_range: 145..146,
delete: 145..146,
2020-03-07 15:27:03 +01:00
insert: "m!($0)",
kind: Macro,
detail: "macro_rules! m",
},
CompletionItem {
label: "quux(…)",
2020-04-24 23:51:02 +02:00
source_range: 145..146,
delete: 145..146,
2020-03-07 15:27:03 +01:00
insert: "quux(${1:x})$0",
kind: Function,
lookup: "quux",
detail: "fn quux(x: i32)",
2020-03-12 19:02:55 +01:00
trigger_call_info: true,
2020-03-07 15:27:03 +01:00
},
CompletionItem {
label: "x",
2020-04-24 23:51:02 +02:00
source_range: 145..146,
delete: 145..146,
2020-03-07 15:27:03 +01:00
insert: "x",
kind: Binding,
detail: "i32",
},
CompletionItem {
label: "y",
2020-04-24 23:51:02 +02:00
source_range: 145..146,
delete: 145..146,
2020-03-15 11:26:54 +01:00
insert: "y",
kind: Binding,
detail: "i32",
},
]
"###
);
}
#[test]
fn completes_in_simple_macro_without_closing_parens() {
assert_debug_snapshot!(
do_reference_completion(
r"
macro_rules! m { ($e:expr) => { $e } }
fn quux(x: i32) {
let y = 92;
m!(x<|>
}
"
),
@r###"
[
CompletionItem {
2020-04-24 13:15:39 +02:00
label: "m!(…)",
2020-04-24 23:51:02 +02:00
source_range: 145..146,
delete: 145..146,
2020-03-15 11:26:54 +01:00
insert: "m!($0)",
kind: Macro,
detail: "macro_rules! m",
},
CompletionItem {
label: "quux(…)",
2020-04-24 23:51:02 +02:00
source_range: 145..146,
delete: 145..146,
2020-03-15 11:26:54 +01:00
insert: "quux(${1:x})$0",
kind: Function,
lookup: "quux",
detail: "fn quux(x: i32)",
trigger_call_info: true,
},
CompletionItem {
label: "x",
2020-04-24 23:51:02 +02:00
source_range: 145..146,
delete: 145..146,
2020-03-15 11:26:54 +01:00
insert: "x",
kind: Binding,
detail: "i32",
},
CompletionItem {
label: "y",
2020-04-24 23:51:02 +02:00
source_range: 145..146,
delete: 145..146,
2020-03-07 15:27:03 +01:00
insert: "y",
kind: Binding,
detail: "i32",
},
]
"###
);
}
#[test]
fn completes_unresolved_uses() {
assert_debug_snapshot!(
do_reference_completion(
r"
use spam::Quux;
fn main() {
<|>
}
"
),
@r###"
[
CompletionItem {
label: "Quux",
2020-04-24 23:51:02 +02:00
source_range: 82..82,
delete: 82..82,
insert: "Quux",
},
CompletionItem {
label: "main()",
2020-04-24 23:51:02 +02:00
source_range: 82..82,
delete: 82..82,
insert: "main()$0",
kind: Function,
lookup: "main",
detail: "fn main()",
},
]
"###
);
}
#[test]
fn completes_enum_variant_matcharm() {
assert_debug_snapshot!(
do_reference_completion(
r"
enum Foo {
Bar,
Baz,
Quux
}
fn main() {
let foo = Foo::Quux;
match foo {
Qu<|>
}
}
"
),
@r###"
[
CompletionItem {
label: "Foo",
2020-04-24 23:51:02 +02:00
source_range: 248..250,
delete: 248..250,
insert: "Foo",
kind: Enum,
},
CompletionItem {
label: "Foo::Bar",
2020-04-24 23:51:02 +02:00
source_range: 248..250,
delete: 248..250,
insert: "Foo::Bar",
kind: EnumVariant,
lookup: "Bar",
detail: "()",
},
CompletionItem {
label: "Foo::Baz",
2020-04-24 23:51:02 +02:00
source_range: 248..250,
delete: 248..250,
insert: "Foo::Baz",
kind: EnumVariant,
lookup: "Baz",
detail: "()",
},
CompletionItem {
label: "Foo::Quux",
2020-04-24 23:51:02 +02:00
source_range: 248..250,
delete: 248..250,
insert: "Foo::Quux",
kind: EnumVariant,
lookup: "Quux",
detail: "()",
},
]
"###
)
}
#[test]
fn completes_enum_variant_iflet() {
assert_debug_snapshot!(
do_reference_completion(
r"
enum Foo {
Bar,
Baz,
Quux
}
fn main() {
let foo = Foo::Quux;
if let Qu<|> = foo {
}
}
"
),
@r###"
[
CompletionItem {
label: "Foo",
2020-04-24 23:51:02 +02:00
source_range: 219..221,
delete: 219..221,
insert: "Foo",
kind: Enum,
},
CompletionItem {
label: "Foo::Bar",
2020-04-24 23:51:02 +02:00
source_range: 219..221,
delete: 219..221,
insert: "Foo::Bar",
kind: EnumVariant,
lookup: "Bar",
detail: "()",
},
CompletionItem {
label: "Foo::Baz",
2020-04-24 23:51:02 +02:00
source_range: 219..221,
delete: 219..221,
insert: "Foo::Baz",
kind: EnumVariant,
lookup: "Baz",
detail: "()",
},
CompletionItem {
label: "Foo::Quux",
2020-04-24 23:51:02 +02:00
source_range: 219..221,
delete: 219..221,
insert: "Foo::Quux",
kind: EnumVariant,
lookup: "Quux",
detail: "()",
},
]
"###
)
}
#[test]
fn completes_enum_variant_basic_expr() {
assert_debug_snapshot!(
do_reference_completion(
r"
enum Foo {
Bar,
Baz,
Quux
}
fn main() {
let foo: Foo = Q<|>
}
"
),
@r###"
[
CompletionItem {
label: "Foo",
2020-04-24 23:51:02 +02:00
source_range: 185..186,
delete: 185..186,
insert: "Foo",
kind: Enum,
},
CompletionItem {
label: "Foo::Bar",
2020-04-24 23:51:02 +02:00
source_range: 185..186,
delete: 185..186,
insert: "Foo::Bar",
kind: EnumVariant,
lookup: "Bar",
detail: "()",
},
CompletionItem {
label: "Foo::Baz",
2020-04-24 23:51:02 +02:00
source_range: 185..186,
delete: 185..186,
insert: "Foo::Baz",
kind: EnumVariant,
lookup: "Baz",
detail: "()",
},
CompletionItem {
label: "Foo::Quux",
2020-04-24 23:51:02 +02:00
source_range: 185..186,
delete: 185..186,
insert: "Foo::Quux",
kind: EnumVariant,
lookup: "Quux",
detail: "()",
},
CompletionItem {
label: "main()",
2020-04-24 23:51:02 +02:00
source_range: 185..186,
delete: 185..186,
insert: "main()$0",
kind: Function,
lookup: "main",
detail: "fn main()",
},
]
"###
)
}
#[test]
fn completes_enum_variant_from_module() {
assert_debug_snapshot!(
do_reference_completion(
r"
mod m { pub enum E { V } }
fn f() -> m::E {
V<|>
}
"
),
@r###"
[
CompletionItem {
label: "f()",
2020-04-25 11:52:10 +02:00
source_range: 98..99,
delete: 98..99,
insert: "f()$0",
kind: Function,
lookup: "f",
detail: "fn f() -> m::E",
},
CompletionItem {
label: "m",
2020-04-25 11:52:10 +02:00
source_range: 98..99,
delete: 98..99,
insert: "m",
kind: Module,
},
CompletionItem {
label: "m::E::V",
2020-04-25 11:52:10 +02:00
source_range: 98..99,
delete: 98..99,
insert: "m::E::V",
kind: EnumVariant,
lookup: "V",
detail: "()",
},
]
"###
)
}
2020-05-04 16:48:50 +02:00
#[test]
fn dont_complete_attr() {
assert_debug_snapshot!(
do_reference_completion(
r"
struct Foo;
#[<|>]
fn f() {}
"
),
@r###"[]"###
)
}
2019-01-08 22:33:36 +03:00
}