//! FIXME: write short doc here use crate::completion::{CompletionContext, Completions}; pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { if !ctx.is_trivial_path { return; } ctx.scope().process_all_names(&mut |name, res| acc.add_resolution(ctx, name.to_string(), &res)); } #[cfg(test)] mod tests { use insta::assert_debug_snapshot; use crate::completion::{do_completion, CompletionItem, CompletionKind}; fn do_reference_completion(code: &str) -> Vec { do_completion(code, CompletionKind::Reference) } #[test] fn completes_bindings_from_let() { assert_debug_snapshot!( do_reference_completion( r" fn quux(x: i32) { let y = 92; 1 + <|>; let z = (); } " ), @r###" [ CompletionItem { label: "quux(…)", source_range: [91; 91), delete: [91; 91), insert: "quux(${1:x})$0", kind: Function, lookup: "quux", detail: "fn quux(x: i32)", }, CompletionItem { label: "x", source_range: [91; 91), delete: [91; 91), insert: "x", kind: Binding, detail: "i32", }, CompletionItem { label: "y", source_range: [91; 91), delete: [91; 91), insert: "y", kind: Binding, detail: "i32", }, ] "### ); } #[test] fn completes_bindings_from_if_let() { 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 + <|> } } " ), @r###" [ CompletionItem { label: "a", source_range: [242; 242), delete: [242; 242), insert: "a", kind: Binding, }, CompletionItem { label: "b", source_range: [242; 242), delete: [242; 242), insert: "b", kind: Binding, detail: "i32", }, CompletionItem { label: "quux()", source_range: [242; 242), delete: [242; 242), insert: "quux()$0", kind: Function, lookup: "quux", detail: "fn quux()", }, ] "### ); } #[test] fn completes_bindings_from_for() { assert_debug_snapshot!( do_reference_completion( r" fn quux() { for x in &[1, 2, 3] { <|> } } " ), @r###" [ CompletionItem { label: "quux()", source_range: [95; 95), delete: [95; 95), insert: "quux()$0", kind: Function, lookup: "quux", detail: "fn quux()", }, CompletionItem { label: "x", source_range: [95; 95), delete: [95; 95), insert: "x", kind: Binding, }, ] "### ); } #[test] fn completes_generic_params() { assert_debug_snapshot!( do_reference_completion( r" fn quux() { <|> } " ), @r###" [ CompletionItem { label: "T", source_range: [52; 52), delete: [52; 52), insert: "T", kind: TypeParam, }, CompletionItem { label: "quux()", source_range: [52; 52), delete: [52; 52), insert: "quux()$0", kind: Function, lookup: "quux", detail: "fn quux()", }, ] "### ); } #[test] fn completes_generic_params_in_struct() { assert_debug_snapshot!( do_reference_completion( r" struct X { x: <|> } " ), @r###" [ CompletionItem { label: "Self", source_range: [54; 54), delete: [54; 54), insert: "Self", kind: TypeParam, }, CompletionItem { label: "T", source_range: [54; 54), delete: [54; 54), insert: "T", kind: TypeParam, }, CompletionItem { label: "X<…>", source_range: [54; 54), delete: [54; 54), insert: "X<$0>", kind: Struct, lookup: "X", }, ] "### ); } #[test] fn completes_self_in_enum() { assert_debug_snapshot!( do_reference_completion( r" enum X { Y(<|>) } " ), @r###" [ CompletionItem { label: "Self", source_range: [48; 48), delete: [48; 48), insert: "Self", kind: TypeParam, }, CompletionItem { label: "X", source_range: [48; 48), delete: [48; 48), insert: "X", kind: Enum, }, ] "### ); } #[test] fn completes_module_items() { assert_debug_snapshot!( do_reference_completion( r" struct Foo; enum Baz {} fn quux() { <|> } " ), @r###" [ CompletionItem { label: "Baz", source_range: [105; 105), delete: [105; 105), insert: "Baz", kind: Enum, }, CompletionItem { label: "Foo", source_range: [105; 105), delete: [105; 105), insert: "Foo", kind: Struct, }, CompletionItem { label: "quux()", source_range: [105; 105), delete: [105; 105), insert: "quux()$0", kind: Function, lookup: "quux", detail: "fn quux()", }, ] "### ); } #[test] fn completes_extern_prelude() { assert_debug_snapshot!( do_reference_completion( r" //- /lib.rs use <|>; //- /other_crate/lib.rs // nothing here " ), @r###" [ CompletionItem { label: "other_crate", source_range: [4; 4), delete: [4; 4), insert: "other_crate", kind: Module, }, ] "### ); } #[test] fn completes_module_items_in_nested_modules() { assert_debug_snapshot!( do_reference_completion( r" struct Foo; mod m { struct Bar; fn quux() { <|> } } " ), @r###" [ CompletionItem { label: "Bar", source_range: [117; 117), delete: [117; 117), insert: "Bar", kind: Struct, }, CompletionItem { label: "quux()", source_range: [117; 117), delete: [117; 117), insert: "quux()$0", kind: Function, lookup: "quux", detail: "fn quux()", }, ] "### ); } #[test] fn completes_return_type() { assert_debug_snapshot!( do_reference_completion( r" struct Foo; fn x() -> <|> " ), @r###" [ CompletionItem { label: "Foo", source_range: [55; 55), delete: [55; 55), insert: "Foo", kind: Struct, }, CompletionItem { label: "x()", source_range: [55; 55), delete: [55; 55), insert: "x()$0", kind: Function, lookup: "x", detail: "fn x()", }, ] "### ); } #[test] fn dont_show_both_completions_for_shadowing() { assert_debug_snapshot!( do_reference_completion( r" fn foo() { let bar = 92; { let bar = 62; <|> } } " ), @r###" [ CompletionItem { label: "bar", source_range: [146; 146), delete: [146; 146), insert: "bar", kind: Binding, detail: "i32", }, CompletionItem { label: "foo()", source_range: [146; 146), delete: [146; 146), insert: "foo()$0", kind: Function, lookup: "foo", detail: "fn foo()", }, ] "### ); } #[test] fn completes_self_in_methods() { assert_debug_snapshot!( do_reference_completion(r"impl S { fn foo(&self) { <|> } }"), @r###" [ CompletionItem { label: "Self", source_range: [25; 25), delete: [25; 25), insert: "Self", kind: TypeParam, }, CompletionItem { label: "self", source_range: [25; 25), delete: [25; 25), insert: "self", kind: Binding, detail: "&{unknown}", }, ] "### ); } #[test] fn completes_prelude() { assert_debug_snapshot!( do_reference_completion( " //- /main.rs fn foo() { let x: <|> } //- /std/lib.rs #[prelude_import] use prelude::*; mod prelude { struct Option; } " ), @r###" [ CompletionItem { label: "Option", source_range: [18; 18), delete: [18; 18), insert: "Option", kind: Struct, }, CompletionItem { label: "foo()", source_range: [18; 18), delete: [18; 18), insert: "foo()$0", kind: Function, lookup: "foo", detail: "fn foo()", }, CompletionItem { label: "std", source_range: [18; 18), delete: [18; 18), insert: "std", kind: Module, }, ] "### ); } #[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", source_range: [18; 18), delete: [18; 18), insert: "String", kind: Struct, }, CompletionItem { label: "core", source_range: [18; 18), delete: [18; 18), insert: "core", kind: Module, }, CompletionItem { label: "foo()", source_range: [18; 18), delete: [18; 18), insert: "foo()$0", kind: Function, lookup: "foo", detail: "fn foo()", }, CompletionItem { label: "std", source_range: [18; 18), delete: [18; 18), insert: "std", kind: Module, }, ] "### ); } #[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 { label: "bar!", source_range: [252; 252), delete: [252; 252), insert: "bar!($0)", kind: Macro, detail: "macro_rules! bar", }, CompletionItem { label: "baz!", source_range: [252; 252), delete: [252; 252), insert: "baz!($0)", kind: Macro, detail: "#[macro_export]\nmacro_rules! baz", }, CompletionItem { label: "foo!", source_range: [252; 252), delete: [252; 252), insert: "foo!($0)", kind: Macro, detail: "macro_rules! foo", }, CompletionItem { label: "m1", source_range: [252; 252), delete: [252; 252), insert: "m1", kind: Module, }, CompletionItem { label: "m2", source_range: [252; 252), delete: [252; 252), insert: "m2", kind: Module, }, CompletionItem { label: "main()", source_range: [252; 252), delete: [252; 252), insert: "main()$0", kind: Function, lookup: "main", detail: "fn main()", }, ] "### ); } #[test] fn completes_both_macro_and_value() { assert_debug_snapshot!( do_reference_completion( " //- /main.rs macro_rules! foo { () => {} } fn foo() { <|> } " ), @r###" [ CompletionItem { label: "foo!", source_range: [49; 49), delete: [49; 49), insert: "foo!($0)", kind: Macro, detail: "macro_rules! foo", }, CompletionItem { label: "foo()", source_range: [49; 49), delete: [49; 49), insert: "foo()$0", kind: Function, lookup: "foo", detail: "fn foo()", }, ] "### ); } #[test] fn completes_macros_as_type() { assert_debug_snapshot!( do_reference_completion( " //- /main.rs macro_rules! foo { () => {} } fn main() { let x: <|> } " ), @r###" [ CompletionItem { label: "foo!", source_range: [57; 57), delete: [57; 57), insert: "foo!($0)", kind: Macro, detail: "macro_rules! foo", }, CompletionItem { label: "main()", source_range: [57; 57), delete: [57; 57), insert: "main()$0", kind: Function, lookup: "main", detail: "fn main()", }, ] "### ); } #[test] fn completes_macros_as_stmt() { assert_debug_snapshot!( do_reference_completion( " //- /main.rs macro_rules! foo { () => {} } fn main() { <|> } " ), @r###" [ CompletionItem { label: "foo!", source_range: [50; 50), delete: [50; 50), insert: "foo!($0)", kind: Macro, detail: "macro_rules! foo", }, CompletionItem { label: "main()", source_range: [50; 50), delete: [50; 50), insert: "main()$0", kind: Function, lookup: "main", detail: "fn main()", }, ] "### ); } #[test] fn completes_local_item() { assert_debug_snapshot!( do_reference_completion( " //- /main.rs fn main() { return f<|>; fn frobnicate() {} } " ), @r###" [ CompletionItem { label: "frobnicate()", source_range: [23; 24), delete: [23; 24), insert: "frobnicate()$0", kind: Function, lookup: "frobnicate", detail: "fn frobnicate()", }, CompletionItem { label: "main()", source_range: [23; 24), delete: [23; 24), insert: "main()$0", kind: Function, lookup: "main", detail: "fn main()", }, ] "### ) } }