From 722489e3ff4c16dc179d30e729847314c918511f Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 27 Oct 2021 16:24:42 +0200 Subject: [PATCH 1/2] Remove filtered completion list usage in completion tests --- crates/ide_completion/src/completions/dot.rs | 371 +++++- .../src/completions/flyimport.rs | 1015 ----------------- .../ide_completion/src/completions/keyword.rs | 295 +---- crates/ide_completion/src/completions/mod_.rs | 3 +- .../ide_completion/src/completions/postfix.rs | 6 +- .../src/completions/qualified_path.rs | 7 +- .../src/completions/trait_impl.rs | 79 +- .../src/completions/unqualified_path.rs | 17 +- crates/ide_completion/src/context.rs | 1 - crates/ide_completion/src/tests.rs | 63 +- crates/ide_completion/src/tests/expression.rs | 219 +++- crates/ide_completion/src/tests/flyimport.rs | 1014 ++++++++++++++++ crates/ide_completion/src/tests/record.rs | 1 + crates/rust-analyzer/tests/slow-tests/tidy.rs | 1 + 14 files changed, 1746 insertions(+), 1346 deletions(-) create mode 100644 crates/ide_completion/src/tests/flyimport.rs diff --git a/crates/ide_completion/src/completions/dot.rs b/crates/ide_completion/src/completions/dot.rs index 213cb701704a..9649667bd76b 100644 --- a/crates/ide_completion/src/completions/dot.rs +++ b/crates/ide_completion/src/completions/dot.rs @@ -99,13 +99,10 @@ fn complete_methods( mod tests { use expect_test::{expect, Expect}; - use crate::{ - tests::{check_edit, filtered_completion_list}, - CompletionKind, - }; + use crate::tests::{check_edit, completion_list_no_kw}; fn check(ra_fixture: &str, expect: Expect) { - let actual = filtered_completion_list(ra_fixture, CompletionKind::Reference); + let actual = completion_list_no_kw(ra_fixture); expect.assert_eq(&actual); } @@ -122,6 +119,18 @@ fn foo(s: S) { s.$0 } expect![[r#" fd foo u32 me bar() fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); } @@ -138,6 +147,18 @@ impl S { expect![[r#" fd the_field (u32,) me foo() fn(self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ) } @@ -154,6 +175,18 @@ impl A { expect![[r#" fd the_field (u32, i32) me foo() fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ) } @@ -166,7 +199,18 @@ impl A { struct A { the_field: u32 } fn foo(a: A) { a.$0() } "#, - expect![[""]], + expect![[r#" + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + "#]], ); } @@ -191,6 +235,18 @@ fn foo(a: lib::m::A) { a.$0 } fd pub_field u32 fd crate_field u32 fd super_field u32 + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); @@ -210,6 +266,18 @@ fn foo(a: lib::m::A) { a.$0 } "#, expect![[r#" fd pub_field u32 + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); @@ -226,7 +294,19 @@ pub mod m { fn foo(a: lib::m::A) { a.$0 } "#, expect![[r#" - fd 1 f64 + fd 1 f64 + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); @@ -248,6 +328,18 @@ fn foo(a: lib::A) { a.$0 } me private_method() fn(&self) me crate_method() fn(&self) me pub_method() fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); check( @@ -266,6 +358,18 @@ fn foo(a: lib::A) { a.$0 } "#, expect![[r#" me pub_method() fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); } @@ -293,6 +397,18 @@ impl A { expect![[r#" fd pub_field u32 me pub_method() fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ) } @@ -307,6 +423,18 @@ fn foo(u: U) { u.$0 } expect![[r#" fd field u8 fd other u16 + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); } @@ -326,6 +454,18 @@ fn foo(a: A) { a.$0 } "#, expect![[r#" me the_method() fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ) } @@ -341,6 +481,18 @@ fn foo(a: A) { a.$0 } "#, expect![[r#" me the_method() (as Trait) fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); check_edit( @@ -371,6 +523,18 @@ fn foo(a: &A) { a.$0 } ", expect![[r#" me the_method() (as Trait) fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); } @@ -389,6 +553,18 @@ fn foo(a: A) { a.$0 } ", expect![[r#" me the_method() (as Trait) fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); } @@ -405,7 +581,20 @@ fn foo(a: A) { a.$0 } "#, - expect![[""]], + expect![[r#" + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut + "#]], ); } @@ -419,8 +608,20 @@ fn foo() { } "#, expect![[r#" - fd 0 i32 - fd 1 f64 + fd 0 i32 + fd 1 f64 + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); } @@ -436,8 +637,20 @@ fn foo() { } "#, expect![[r#" - fd 0 i32 - fd 1 f64 + fd 0 i32 + fd 1 f64 + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); } @@ -460,6 +673,18 @@ impl T { "#, expect![[r#" me blah() fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); } @@ -475,6 +700,18 @@ const X: u32 = { "#, expect![[r#" fd the_field u32 + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); } @@ -491,6 +728,16 @@ fn foo(a: A) { "#, expect![[r#" fd the_field u32 + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) "#]], ); } @@ -508,6 +755,16 @@ fn foo(a: A) { "#, expect![[r#" fd the_field u32 + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) "#]], ); } @@ -524,6 +781,16 @@ fn foo(a: A) { "#, expect![[r#" fd the_field u32 + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) "#]], ); } @@ -550,6 +817,16 @@ fn foo(a: A) { "#, expect![[r#" fd the_field u32 + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) "#]], ); } @@ -569,6 +846,18 @@ fn foo() { "#, expect![[r#" me the_method() fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); } @@ -584,6 +873,18 @@ fn main() { make_s!().f$0; } "#, expect![[r#" me foo() fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ) } @@ -612,6 +913,18 @@ mod foo { "#, expect![[r#" me private() fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); } @@ -639,6 +952,16 @@ impl S { "#, expect![[r#" me foo() fn(&self) -> &[u8] + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) "#]], ); } @@ -654,6 +977,7 @@ impl Foo { fn foo(&self) { $0 } }"#, lc self &Foo sp Self st Foo + bt u32 fd self.field i32 me self.foo() fn(&self) "#]], @@ -667,6 +991,7 @@ impl Foo { fn foo(&mut self) { $0 } }"#, lc self &mut Foo sp Self st Foo + bt u32 fd self.0 i32 me self.foo() fn(&mut self) "#]], @@ -694,6 +1019,16 @@ fn f() { "#, expect![[r#" me method() fn(&self) + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) "#]], ); } @@ -716,6 +1051,18 @@ fn main() { "#, expect![[r#" me into_iter() (as IntoIterator) fn(self) -> ::IntoIter + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ) } diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs index d7c8c54315c4..486cbff68598 100644 --- a/crates/ide_completion/src/completions/flyimport.rs +++ b/crates/ide_completion/src/completions/flyimport.rs @@ -219,1018 +219,3 @@ fn compute_fuzzy_completion_order_key( None => usize::MAX, } } - -#[cfg(test)] -mod tests { - use expect_test::{expect, Expect}; - - use crate::{ - item::CompletionKind, - tests::{check_edit, check_edit_with_config, filtered_completion_list, TEST_CONFIG}, - }; - - fn check(ra_fixture: &str, expect: Expect) { - let actual = filtered_completion_list(ra_fixture, CompletionKind::Magic); - expect.assert_eq(&actual); - } - - #[test] - fn function_fuzzy_completion() { - check_edit( - "stdin", - r#" -//- /lib.rs crate:dep -pub mod io { - pub fn stdin() {} -}; - -//- /main.rs crate:main deps:dep -fn main() { - stdi$0 -} -"#, - r#" -use dep::io::stdin; - -fn main() { - stdin()$0 -} -"#, - ); - } - - #[test] - fn macro_fuzzy_completion() { - check_edit( - "macro_with_curlies!", - r#" -//- /lib.rs crate:dep -/// Please call me as macro_with_curlies! {} -#[macro_export] -macro_rules! macro_with_curlies { - () => {} -} - -//- /main.rs crate:main deps:dep -fn main() { - curli$0 -} -"#, - r#" -use dep::macro_with_curlies; - -fn main() { - macro_with_curlies! {$0} -} -"#, - ); - } - - #[test] - fn struct_fuzzy_completion() { - check_edit( - "ThirdStruct", - r#" -//- /lib.rs crate:dep -pub struct FirstStruct; -pub mod some_module { - pub struct SecondStruct; - pub struct ThirdStruct; -} - -//- /main.rs crate:main deps:dep -use dep::{FirstStruct, some_module::SecondStruct}; - -fn main() { - this$0 -} -"#, - r#" -use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}}; - -fn main() { - ThirdStruct -} -"#, - ); - } - - #[test] - fn short_paths_are_ignored() { - cov_mark::check!(ignore_short_input_for_path); - - check( - r#" -//- /lib.rs crate:dep -pub struct FirstStruct; -pub mod some_module { - pub struct SecondStruct; - pub struct ThirdStruct; -} - -//- /main.rs crate:main deps:dep -use dep::{FirstStruct, some_module::SecondStruct}; - -fn main() { - t$0 -} -"#, - expect![[r#""#]], - ); - } - - #[test] - fn fuzzy_completions_come_in_specific_order() { - cov_mark::check!(certain_fuzzy_order_test); - check( - r#" -//- /lib.rs crate:dep -pub struct FirstStruct; -pub mod some_module { - // already imported, omitted - pub struct SecondStruct; - // does not contain all letters from the query, omitted - pub struct UnrelatedOne; - // contains all letters from the query, but not in sequence, displayed last - pub struct ThiiiiiirdStruct; - // contains all letters from the query, but not in the beginning, displayed second - pub struct AfterThirdStruct; - // contains all letters from the query in the begginning, displayed first - pub struct ThirdStruct; -} - -//- /main.rs crate:main deps:dep -use dep::{FirstStruct, some_module::SecondStruct}; - -fn main() { - hir$0 -} -"#, - expect![[r#" - st ThirdStruct (use dep::some_module::ThirdStruct) - st AfterThirdStruct (use dep::some_module::AfterThirdStruct) - st ThiiiiiirdStruct (use dep::some_module::ThiiiiiirdStruct) - "#]], - ); - } - - #[test] - fn trait_function_fuzzy_completion() { - let fixture = r#" - //- /lib.rs crate:dep - pub mod test_mod { - pub trait TestTrait { - const SPECIAL_CONST: u8; - type HumbleType; - fn weird_function(); - fn random_method(&self); - } - pub struct TestStruct {} - impl TestTrait for TestStruct { - const SPECIAL_CONST: u8 = 42; - type HumbleType = (); - fn weird_function() {} - fn random_method(&self) {} - } - } - - //- /main.rs crate:main deps:dep - fn main() { - dep::test_mod::TestStruct::wei$0 - } - "#; - - check( - fixture, - expect![[r#" - fn weird_function() (use dep::test_mod::TestTrait) fn() - "#]], - ); - - check_edit( - "weird_function", - fixture, - r#" -use dep::test_mod::TestTrait; - -fn main() { - dep::test_mod::TestStruct::weird_function()$0 -} -"#, - ); - } - - #[test] - fn trait_const_fuzzy_completion() { - let fixture = r#" - //- /lib.rs crate:dep - pub mod test_mod { - pub trait TestTrait { - const SPECIAL_CONST: u8; - type HumbleType; - fn weird_function(); - fn random_method(&self); - } - pub struct TestStruct {} - impl TestTrait for TestStruct { - const SPECIAL_CONST: u8 = 42; - type HumbleType = (); - fn weird_function() {} - fn random_method(&self) {} - } - } - - //- /main.rs crate:main deps:dep - fn main() { - dep::test_mod::TestStruct::spe$0 - } - "#; - - check( - fixture, - expect![[r#" - ct SPECIAL_CONST (use dep::test_mod::TestTrait) - "#]], - ); - - check_edit( - "SPECIAL_CONST", - fixture, - r#" -use dep::test_mod::TestTrait; - -fn main() { - dep::test_mod::TestStruct::SPECIAL_CONST -} -"#, - ); - } - - #[test] - fn trait_method_fuzzy_completion() { - let fixture = r#" - //- /lib.rs crate:dep - pub mod test_mod { - pub trait TestTrait { - const SPECIAL_CONST: u8; - type HumbleType; - fn weird_function(); - fn random_method(&self); - } - pub struct TestStruct {} - impl TestTrait for TestStruct { - const SPECIAL_CONST: u8 = 42; - type HumbleType = (); - fn weird_function() {} - fn random_method(&self) {} - } - } - - //- /main.rs crate:main deps:dep - fn main() { - let test_struct = dep::test_mod::TestStruct {}; - test_struct.ran$0 - } - "#; - - check( - fixture, - expect![[r#" - me random_method() (use dep::test_mod::TestTrait) fn(&self) - "#]], - ); - - check_edit( - "random_method", - fixture, - r#" -use dep::test_mod::TestTrait; - -fn main() { - let test_struct = dep::test_mod::TestStruct {}; - test_struct.random_method()$0 -} -"#, - ); - } - - #[test] - fn no_trait_type_fuzzy_completion() { - check( - r#" -//- /lib.rs crate:dep -pub mod test_mod { - pub trait TestTrait { - const SPECIAL_CONST: u8; - type HumbleType; - fn weird_function(); - fn random_method(&self); - } - pub struct TestStruct {} - impl TestTrait for TestStruct { - const SPECIAL_CONST: u8 = 42; - type HumbleType = (); - fn weird_function() {} - fn random_method(&self) {} - } -} - -//- /main.rs crate:main deps:dep -fn main() { - dep::test_mod::TestStruct::hum$0 -} -"#, - expect![[r#""#]], - ); - } - - #[test] - fn does_not_propose_names_in_scope() { - check( - r#" -//- /lib.rs crate:dep -pub mod test_mod { - pub trait TestTrait { - const SPECIAL_CONST: u8; - type HumbleType; - fn weird_function(); - fn random_method(&self); - } - pub struct TestStruct {} - impl TestTrait for TestStruct { - const SPECIAL_CONST: u8 = 42; - type HumbleType = (); - fn weird_function() {} - fn random_method(&self) {} - } -} - -//- /main.rs crate:main deps:dep -use dep::test_mod::TestStruct; -fn main() { - TestSt$0 -} -"#, - expect![[r#""#]], - ); - } - - #[test] - fn does_not_propose_traits_in_scope() { - check( - r#" -//- /lib.rs crate:dep -pub mod test_mod { - pub trait TestTrait { - const SPECIAL_CONST: u8; - type HumbleType; - fn weird_function(); - fn random_method(&self); - } - pub struct TestStruct {} - impl TestTrait for TestStruct { - const SPECIAL_CONST: u8 = 42; - type HumbleType = (); - fn weird_function() {} - fn random_method(&self) {} - } -} - -//- /main.rs crate:main deps:dep -use dep::test_mod::{TestStruct, TestTrait}; -fn main() { - dep::test_mod::TestStruct::hum$0 -} -"#, - expect![[r#""#]], - ); - } - - #[test] - fn blanket_trait_impl_import() { - check_edit( - "another_function", - r#" -//- /lib.rs crate:dep -pub mod test_mod { - pub struct TestStruct {} - pub trait TestTrait { - fn another_function(); - } - impl TestTrait for T { - fn another_function() {} - } -} - -//- /main.rs crate:main deps:dep -fn main() { - dep::test_mod::TestStruct::ano$0 -} -"#, - r#" -use dep::test_mod::TestTrait; - -fn main() { - dep::test_mod::TestStruct::another_function()$0 -} -"#, - ); - } - - #[test] - fn zero_input_deprecated_assoc_item_completion() { - check( - r#" -//- /lib.rs crate:dep -pub mod test_mod { - #[deprecated] - pub trait TestTrait { - const SPECIAL_CONST: u8; - type HumbleType; - fn weird_function(); - fn random_method(&self); - } - pub struct TestStruct {} - impl TestTrait for TestStruct { - const SPECIAL_CONST: u8 = 42; - type HumbleType = (); - fn weird_function() {} - fn random_method(&self) {} - } -} - -//- /main.rs crate:main deps:dep -fn main() { - let test_struct = dep::test_mod::TestStruct {}; - test_struct.$0 -} - "#, - expect![[r#" - me random_method() (use dep::test_mod::TestTrait) fn(&self) DEPRECATED - "#]], - ); - - check( - r#" -//- /lib.rs crate:dep -pub mod test_mod { - #[deprecated] - pub trait TestTrait { - const SPECIAL_CONST: u8; - type HumbleType; - fn weird_function(); - fn random_method(&self); - } - pub struct TestStruct {} - impl TestTrait for TestStruct { - const SPECIAL_CONST: u8 = 42; - type HumbleType = (); - fn weird_function() {} - fn random_method(&self) {} - } -} - -//- /main.rs crate:main deps:dep -fn main() { - dep::test_mod::TestStruct::$0 -} -"#, - expect![[r#" - fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED - ct SPECIAL_CONST (use dep::test_mod::TestTrait) DEPRECATED - "#]], - ); - } - - #[test] - fn no_completions_in_use_statements() { - check( - r#" -//- /lib.rs crate:dep -pub mod io { - pub fn stdin() {} -}; - -//- /main.rs crate:main deps:dep -use stdi$0 - -fn main() {} -"#, - expect![[]], - ); - } - - #[test] - fn prefix_config_usage() { - let fixture = r#" -mod foo { - pub mod bar { - pub struct Item; - } -} - -use crate::foo::bar; - -fn main() { - Ite$0 -}"#; - let mut config = TEST_CONFIG; - - config.insert_use.prefix_kind = hir::PrefixKind::ByCrate; - check_edit_with_config( - config.clone(), - "Item", - fixture, - r#" -mod foo { - pub mod bar { - pub struct Item; - } -} - -use crate::foo::bar::{self, Item}; - -fn main() { - Item -}"#, - ); - - config.insert_use.prefix_kind = hir::PrefixKind::BySelf; - check_edit_with_config( - config.clone(), - "Item", - fixture, - r#" -mod foo { - pub mod bar { - pub struct Item; - } -} - -use crate::foo::bar; - -use self::foo::bar::Item; - -fn main() { - Item -}"#, - ); - - config.insert_use.prefix_kind = hir::PrefixKind::Plain; - check_edit_with_config( - config, - "Item", - fixture, - r#" -mod foo { - pub mod bar { - pub struct Item; - } -} - -use foo::bar::Item; - -use crate::foo::bar; - -fn main() { - Item -}"#, - ); - } - - #[test] - fn unresolved_qualifier() { - let fixture = r#" -mod foo { - pub mod bar { - pub mod baz { - pub struct Item; - } - } -} - -fn main() { - bar::baz::Ite$0 -}"#; - - check( - fixture, - expect![[r#" - st Item (use foo::bar::baz::Item) - "#]], - ); - - check_edit( - "Item", - fixture, - r#" - use foo::bar; - - mod foo { - pub mod bar { - pub mod baz { - pub struct Item; - } - } - } - - fn main() { - bar::baz::Item - }"#, - ); - } - - #[test] - fn unresolved_assoc_item_container() { - let fixture = r#" -mod foo { - pub struct Item; - - impl Item { - pub const TEST_ASSOC: usize = 3; - } -} - -fn main() { - Item::TEST_A$0 -}"#; - - check( - fixture, - expect![[r#" - ct TEST_ASSOC (use foo::Item) - "#]], - ); - - check_edit( - "TEST_ASSOC", - fixture, - r#" -use foo::Item; - -mod foo { - pub struct Item; - - impl Item { - pub const TEST_ASSOC: usize = 3; - } -} - -fn main() { - Item::TEST_ASSOC -}"#, - ); - } - - #[test] - fn unresolved_assoc_item_container_with_path() { - let fixture = r#" -mod foo { - pub mod bar { - pub struct Item; - - impl Item { - pub const TEST_ASSOC: usize = 3; - } - } -} - -fn main() { - bar::Item::TEST_A$0 -}"#; - - check( - fixture, - expect![[r#" - ct TEST_ASSOC (use foo::bar::Item) - "#]], - ); - - check_edit( - "TEST_ASSOC", - fixture, - r#" -use foo::bar; - -mod foo { - pub mod bar { - pub struct Item; - - impl Item { - pub const TEST_ASSOC: usize = 3; - } - } -} - -fn main() { - bar::Item::TEST_ASSOC -}"#, - ); - } - - #[test] - fn fuzzy_unresolved_path() { - check( - r#" -mod foo { - pub mod bar { - pub struct Item; - - impl Item { - pub const TEST_ASSOC: usize = 3; - } - } -} - -fn main() { - bar::ASS$0 -}"#, - expect![[]], - ) - } - - #[test] - fn unqualified_assoc_items_are_omitted() { - check( - r#" -mod something { - pub trait BaseTrait { - fn test_function() -> i32; - } - - pub struct Item1; - pub struct Item2; - - impl BaseTrait for Item1 { - fn test_function() -> i32 { - 1 - } - } - - impl BaseTrait for Item2 { - fn test_function() -> i32 { - 2 - } - } -} - -fn main() { - test_f$0 -}"#, - expect![[]], - ) - } - - #[test] - fn case_matters() { - check( - r#" -mod foo { - pub const TEST_CONST: usize = 3; - pub fn test_function() -> i32 { - 4 - } -} - -fn main() { - TE$0 -}"#, - expect![[r#" - ct TEST_CONST (use foo::TEST_CONST) - "#]], - ); - - check( - r#" -mod foo { - pub const TEST_CONST: usize = 3; - pub fn test_function() -> i32 { - 4 - } -} - -fn main() { - te$0 -}"#, - expect![[r#" - ct TEST_CONST (use foo::TEST_CONST) - fn test_function() (use foo::test_function) fn() -> i32 - "#]], - ); - - check( - r#" -mod foo { - pub const TEST_CONST: usize = 3; - pub fn test_function() -> i32 { - 4 - } -} - -fn main() { - Te$0 -}"#, - expect![[]], - ); - } - - #[test] - fn no_fuzzy_during_fields_of_record_lit_syntax() { - check( - r#" -mod m { - pub fn some_fn() -> i32 { - 42 - } -} -struct Foo { - some_field: i32, -} -fn main() { - let _ = Foo { so$0 }; -} -"#, - expect![[]], - ); - } - - #[test] - fn fuzzy_after_fields_of_record_lit_syntax() { - check( - r#" -mod m { - pub fn some_fn() -> i32 { - 42 - } -} -struct Foo { - some_field: i32, -} -fn main() { - let _ = Foo { some_field: so$0 }; -} -"#, - expect![[r#" - fn some_fn() (use m::some_fn) fn() -> i32 - "#]], - ); - } - - #[test] - fn no_flyimports_in_traits_and_impl_declarations() { - check( - r#" -mod m { - pub fn some_fn() -> i32 { - 42 - } -} -trait Foo { - som$0 -} -"#, - expect![[r#""#]], - ); - - check( - r#" -mod m { - pub fn some_fn() -> i32 { - 42 - } -} -struct Foo; -impl Foo { - som$0 -} -"#, - expect![[r#""#]], - ); - - check( - r#" -mod m { - pub fn some_fn() -> i32 { - 42 - } -} -struct Foo; -trait Bar {} -impl Bar for Foo { - som$0 -} -"#, - expect![[r#""#]], - ); - } - - #[test] - fn no_inherent_candidates_proposed() { - check( - r#" -mod baz { - pub trait DefDatabase { - fn method1(&self); - } - pub trait HirDatabase: DefDatabase { - fn method2(&self); - } -} - -mod bar { - fn test(db: &dyn crate::baz::HirDatabase) { - db.metho$0 - } -} - "#, - expect![[r#""#]], - ); - } - - #[test] - fn respects_doc_hidden() { - check( - r#" -//- /lib.rs crate:lib deps:dep -fn f() { - ().fro$0 -} - -//- /dep.rs crate:dep -#[doc(hidden)] -pub trait Private { - fn frob(&self) {} -} - -impl Private for T {} - "#, - expect![[r#""#]], - ); - check( - r#" -//- /lib.rs crate:lib deps:dep -fn f() { - ().fro$0 -} - -//- /dep.rs crate:dep -pub trait Private { - #[doc(hidden)] - fn frob(&self) {} -} - -impl Private for T {} - "#, - expect![[r#""#]], - ); - } - - #[test] - fn regression_9760() { - check( - r#" -struct Struct; -fn main() {} - -mod mud { - fn func() { - let struct_instance = Stru$0 - } -} -"#, - expect![[r#" - st Struct (use crate::Struct) - "#]], - ); - } - - #[test] - fn flyimport_pattern() { - check( - r#" -mod module { - pub struct Struct; -} -fn function() { - let Str$0 -} -"#, - expect![[r#" - st Struct (use module::Struct) - "#]], - ); - } - - #[test] - fn flyimport_rename() { - check( - r#" -mod module { - pub struct Struct; -} -use self as Str$0; - "#, - expect![[r#""#]], - ); - } -} diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index 31aabd98d3e6..4fd622f39955 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs @@ -181,115 +181,15 @@ fn add_keyword(ctx: &CompletionContext, acc: &mut Completions, kw: &str, snippet mod tests { use expect_test::{expect, Expect}; - use crate::{ - tests::{check_edit, filtered_completion_list}, - CompletionKind, - }; + use crate::tests::{check_edit, completion_list}; fn check(ra_fixture: &str, expect: Expect) { - let actual = filtered_completion_list(ra_fixture, CompletionKind::Keyword); + let actual = completion_list(ra_fixture); expect.assert_eq(&actual) } #[test] - fn test_keywords_in_function() { - check( - r"fn quux() { $0 }", - expect![[r#" - kw unsafe - kw fn - kw const - kw type - kw impl - kw extern - kw use - kw trait - kw static - kw mod - kw match - kw while - kw while let - kw loop - kw if - kw if let - kw for - kw true - kw false - kw let - kw return - kw self - kw super - kw crate - "#]], - ); - } - - #[test] - fn test_keywords_inside_block() { - check( - r"fn quux() { if true { $0 } }", - expect![[r#" - kw unsafe - kw fn - kw const - kw type - kw impl - kw extern - kw use - kw trait - kw static - kw mod - kw match - kw while - kw while let - kw loop - kw if - kw if let - kw for - kw true - kw false - kw let - kw return - kw self - kw super - kw crate - "#]], - ); - } - - #[test] - fn test_keywords_after_if() { - check( - r#"fn quux() { if true { () } $0 }"#, - expect![[r#" - kw unsafe - kw fn - kw const - kw type - kw impl - kw extern - kw use - kw trait - kw static - kw mod - kw match - kw while - kw while let - kw loop - kw if - kw if let - kw for - kw true - kw false - kw let - kw else - kw else if - kw return - kw self - kw super - kw crate - "#]], - ); + fn test_else_edit_after_if() { check_edit( "else", r#"fn quux() { if true { () } $0 }"#, @@ -299,68 +199,6 @@ mod tests { ); } - #[test] - fn test_keywords_in_match_arm() { - check( - r#" -fn quux() -> i32 { - match () { () => $0 } -} -"#, - expect![[r#" - kw unsafe - kw match - kw while - kw while let - kw loop - kw if - kw if let - kw for - kw true - kw false - kw return - kw self - kw super - kw crate - "#]], - ); - } - - #[test] - fn test_keywords_in_loop() { - check( - r"fn my() { loop { $0 } }", - expect![[r#" - kw unsafe - kw fn - kw const - kw type - kw impl - kw extern - kw use - kw trait - kw static - kw mod - kw match - kw while - kw while let - kw loop - kw if - kw if let - kw for - kw true - kw false - kw let - kw continue - kw break - kw return - kw self - kw super - kw crate - "#]], - ); - } - #[test] fn test_keywords_after_unsafe_in_block_expr() { check( @@ -369,38 +207,12 @@ fn quux() -> i32 { kw fn kw trait kw impl + sn pd + sn ppd "#]], ); } - #[test] - fn no_keyword_completion_in_comments() { - cov_mark::check!(no_keyword_completion_in_comments); - check( - r#" -fn test() { - let x = 2; // A comment$0 -} -"#, - expect![[""]], - ); - check( - r#" -/* -Some multi-line comment$0 -*/ -"#, - expect![[""]], - ); - check( - r#" -/// Some doc comment -/// let test$0 = 1 -"#, - expect![[""]], - ); - } - #[test] fn test_completion_await_impls_future() { check( @@ -413,6 +225,18 @@ fn foo(a: A) { a.$0 } "#, expect![[r#" kw await expr.await + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ); @@ -427,83 +251,22 @@ fn foo() { "#, expect![[r#" kw await expr.await + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut "#]], ) } - #[test] - fn after_let() { - check( - r#"fn main() { let _ = $0 }"#, - expect![[r#" - kw unsafe - kw match - kw while - kw while let - kw loop - kw if - kw if let - kw for - kw true - kw false - kw return - kw self - kw super - kw crate - "#]], - ) - } - - #[test] - fn skip_struct_initializer() { - cov_mark::check!(no_keyword_completion_in_record_lit); - check( - r#" -struct Foo { - pub f: i32, -} -fn foo() { - Foo { - $0 - } -} -"#, - expect![[r#""#]], - ); - } - - #[test] - fn struct_initializer_field_expr() { - check( - r#" -struct Foo { - pub f: i32, -} -fn foo() { - Foo { - f: $0 - } -} -"#, - expect![[r#" - kw unsafe - kw match - kw while - kw while let - kw loop - kw if - kw if let - kw for - kw true - kw false - kw return - kw self - kw super - kw crate - "#]], - ); - } - #[test] fn let_semi() { cov_mark::check!(let_semi); diff --git a/crates/ide_completion/src/completions/mod_.rs b/crates/ide_completion/src/completions/mod_.rs index 1c864c0e708b..c26fa42d1b6b 100644 --- a/crates/ide_completion/src/completions/mod_.rs +++ b/crates/ide_completion/src/completions/mod_.rs @@ -141,9 +141,10 @@ fn module_chain_to_containing_module_file( #[cfg(test)] mod tests { - use crate::tests::completion_list; use expect_test::{expect, Expect}; + use crate::tests::completion_list; + fn check(ra_fixture: &str, expect: Expect) { let actual = completion_list(ra_fixture); expect.assert_eq(&actual); diff --git a/crates/ide_completion/src/completions/postfix.rs b/crates/ide_completion/src/completions/postfix.rs index 4ace346768a6..87b5d6c4720c 100644 --- a/crates/ide_completion/src/completions/postfix.rs +++ b/crates/ide_completion/src/completions/postfix.rs @@ -270,12 +270,12 @@ mod tests { use expect_test::{expect, Expect}; use crate::{ - tests::{check_edit, check_edit_with_config, filtered_completion_list, TEST_CONFIG}, - CompletionConfig, CompletionKind, Snippet, + tests::{check_edit, check_edit_with_config, completion_list, TEST_CONFIG}, + CompletionConfig, Snippet, }; fn check(ra_fixture: &str, expect: Expect) { - let actual = filtered_completion_list(ra_fixture, CompletionKind::Postfix); + let actual = completion_list(ra_fixture); expect.assert_eq(&actual) } diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs index f61baf184bb1..e9d39edc43a2 100644 --- a/crates/ide_completion/src/completions/qualified_path.rs +++ b/crates/ide_completion/src/completions/qualified_path.rs @@ -250,13 +250,10 @@ fn add_enum_variants(acc: &mut Completions, ctx: &CompletionContext, e: hir::Enu mod tests { use expect_test::{expect, Expect}; - use crate::{ - tests::{check_edit, filtered_completion_list}, - CompletionKind, - }; + use crate::tests::{check_edit, completion_list_no_kw}; fn check(ra_fixture: &str, expect: Expect) { - let actual = filtered_completion_list(ra_fixture, CompletionKind::Reference); + let actual = completion_list_no_kw(ra_fixture); expect.assert_eq(&actual); } diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs index 31accd035f7e..37fa001e0cd0 100644 --- a/crates/ide_completion/src/completions/trait_impl.rs +++ b/crates/ide_completion/src/completions/trait_impl.rs @@ -290,13 +290,10 @@ fn replacement_range(ctx: &CompletionContext, item: &SyntaxNode) -> TextRange { mod tests { use expect_test::{expect, Expect}; - use crate::{ - tests::{check_edit, filtered_completion_list}, - CompletionKind, - }; + use crate::tests::{check_edit, completion_list_no_kw}; fn check(ra_fixture: &str, expect: Expect) { - let actual = filtered_completion_list(ra_fixture, CompletionKind::Magic); + let actual = completion_list_no_kw(ra_fixture); expect.assert_eq(&actual) } @@ -313,7 +310,12 @@ impl Test for T { } } ", - expect![[""]], + expect![[r#" + sp Self + tt Test + st T + bt u32 + "#]], ); check( @@ -356,7 +358,23 @@ impl Test for T { } } ", - expect![[""]], + expect![[r#" + sn if if expr {} + sn while while expr {} + sn not !expr + sn ref &expr + sn refm &mut expr + sn match match expr {} + sn box Box::new(expr) + sn ok Ok(expr) + sn err Err(expr) + sn some Some(expr) + sn dbg dbg!(expr) + sn dbgr dbg!(&expr) + sn call function(expr) + sn let let + sn letm let mut + "#]], ); check( @@ -368,7 +386,10 @@ impl Test for T { fn test(t$0) } ", - expect![[""]], + expect![[r#" + sp Self + st T + "#]], ); check( @@ -380,7 +401,10 @@ impl Test for T { fn test(f: fn $0) } ", - expect![[""]], + expect![[r#" + sp Self + st T + "#]], ); } @@ -395,7 +419,7 @@ impl Test for T { const TEST: fn $0 } ", - expect![[""]], + expect![[r#""#]], ); check( @@ -407,7 +431,12 @@ impl Test for T { const TEST: T$0 } ", - expect![[""]], + expect![[r#" + sp Self + tt Test + st T + bt u32 + "#]], ); check( @@ -419,7 +448,12 @@ impl Test for T { const TEST: u32 = f$0 } ", - expect![[""]], + expect![[r#" + sp Self + tt Test + st T + bt u32 + "#]], ); check( @@ -433,7 +467,12 @@ impl Test for T { }; } ", - expect![[""]], + expect![[r#" + sp Self + tt Test + st T + bt u32 + "#]], ); check( @@ -476,7 +515,12 @@ impl Test for T { type Test = T$0; } ", - expect![[""]], + expect![[r#" + sp Self + tt Test + st T + bt u32 + "#]], ); check( @@ -488,7 +532,12 @@ impl Test for T { type Test = fn $0; } ", - expect![[""]], + expect![[r#" + sp Self + tt Test + st T + bt u32 + "#]], ); } diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs index afacf7fe03c0..825fae587b1d 100644 --- a/crates/ide_completion/src/completions/unqualified_path.rs +++ b/crates/ide_completion/src/completions/unqualified_path.rs @@ -117,24 +117,15 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC mod tests { use expect_test::{expect, Expect}; - use crate::{ - tests::{check_edit, filtered_completion_list_with_config, TEST_CONFIG}, - CompletionConfig, CompletionKind, - }; + use crate::tests::{check_edit, completion_list_no_kw}; fn check(ra_fixture: &str, expect: Expect) { - check_with_config(TEST_CONFIG, ra_fixture, expect); - } - - fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) { - let actual = - filtered_completion_list_with_config(config, ra_fixture, CompletionKind::Reference); + let actual = completion_list_no_kw(ra_fixture); expect.assert_eq(&actual) } #[test] fn completes_if_prefix_is_keyword() { - cov_mark::check!(completes_if_prefix_is_keyword); check_edit( "wherewolf", r#" @@ -188,6 +179,7 @@ pub mod prelude { "#, expect![[r#" md std + bt u32 st Option "#]], ); @@ -217,6 +209,7 @@ mod macros { fn f() fn() ma concat!(…) #[macro_export] macro_rules! concat md std + bt u32 "##]], ); } @@ -245,6 +238,7 @@ pub mod prelude { expect![[r#" md std md core + bt u32 st String "#]], ); @@ -273,6 +267,7 @@ pub mod prelude { expect![[r#" fn f() fn() md std + bt u32 "#]], ); } diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index 4e3abff3b3f8..0cb484d50755 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs @@ -134,7 +134,6 @@ impl<'a> CompletionContext<'a> { // check kind of macro-expanded token, but use range of original token let kind = self.token.kind(); if kind == IDENT || kind == LIFETIME_IDENT || kind == UNDERSCORE || kind.is_keyword() { - cov_mark::hit!(completes_if_prefix_is_keyword); self.original_token.text_range() } else if kind == CHAR { // assume we are completing a lifetime but the user has only typed the ' diff --git a/crates/ide_completion/src/tests.rs b/crates/ide_completion/src/tests.rs index 4028fc2242fa..fee61e0bfcf6 100644 --- a/crates/ide_completion/src/tests.rs +++ b/crates/ide_completion/src/tests.rs @@ -20,6 +20,7 @@ mod record; mod type_pos; mod use_tree; mod visibility; +mod flyimport; use std::mem; @@ -77,10 +78,18 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig { }; pub(crate) fn completion_list(ra_fixture: &str) -> String { - completion_list_with_config(TEST_CONFIG, ra_fixture) + completion_list_with_config(TEST_CONFIG, ra_fixture, true) } -fn completion_list_with_config(config: CompletionConfig, ra_fixture: &str) -> String { +pub(crate) fn completion_list_no_kw(ra_fixture: &str) -> String { + completion_list_with_config(TEST_CONFIG, ra_fixture, false) +} + +fn completion_list_with_config( + config: CompletionConfig, + ra_fixture: &str, + include_keywords: bool, +) -> String { // filter out all but one builtintype completion for smaller test outputs let items = get_all_items(config, ra_fixture); let mut bt_seen = false; @@ -89,6 +98,8 @@ fn completion_list_with_config(config: CompletionConfig, ra_fixture: &str) -> St .filter(|it| { it.completion_kind != CompletionKind::BuiltinType || !mem::replace(&mut bt_seen, true) }) + .filter(|it| include_keywords || it.completion_kind != CompletionKind::Keyword) + .filter(|it| include_keywords || it.completion_kind != CompletionKind::Snippet) .collect(); render_completion_list(items) } @@ -120,20 +131,6 @@ pub(crate) fn do_completion_with_config( .collect() } -pub(crate) fn filtered_completion_list(code: &str, kind: CompletionKind) -> String { - filtered_completion_list_with_config(TEST_CONFIG, code, kind) -} - -pub(crate) fn filtered_completion_list_with_config( - config: CompletionConfig, - code: &str, - kind: CompletionKind, -) -> String { - let kind_completions: Vec = - get_all_items(config, code).into_iter().filter(|c| c.completion_kind == kind).collect(); - render_completion_list(kind_completions) -} - fn render_completion_list(completions: Vec) -> String { fn monospace_width(s: &str) -> usize { s.chars().count() @@ -254,3 +251,37 @@ fn foo() { "#, ); } + +#[test] +fn no_completions_in_comments() { + cov_mark::check!(no_keyword_completion_in_comments); + assert_eq!( + completion_list( + r#" +fn test() { +let x = 2; // A comment$0 +} +"#, + ), + String::new(), + ); + assert_eq!( + completion_list( + r#" +/* +Some multi-line comment$0 +*/ +"#, + ), + String::new(), + ); + assert_eq!( + completion_list( + r#" +/// Some doc comment +/// let test$0 = 1 +"#, + ), + String::new(), + ); +} diff --git a/crates/ide_completion/src/tests/expression.rs b/crates/ide_completion/src/tests/expression.rs index 9a42dd7b2751..a63480873447 100644 --- a/crates/ide_completion/src/tests/expression.rs +++ b/crates/ide_completion/src/tests/expression.rs @@ -110,7 +110,7 @@ fn func(param0 @ (param1, param2): (i32, i32)) { } #[test] -fn completes_all_the_things() { +fn completes_all_the_things_in_fn_body() { cov_mark::check!(unqualified_skip_lifetime_completion); check( r#" @@ -206,6 +206,223 @@ impl Unit { ); } +#[test] +fn complete_in_block() { + check_empty( + r#" + fn foo() { + if true { + $0 + } + } +"#, + expect![[r#" + kw unsafe + kw fn + kw const + kw type + kw impl + kw extern + kw use + kw trait + kw static + kw mod + kw match + kw while + kw while let + kw loop + kw if + kw if let + kw for + kw true + kw false + kw let + kw return + sn pd + sn ppd + kw self + kw super + kw crate + fn foo() fn() + bt u32 + "#]], + ) +} + +#[test] +fn complete_after_if_expr() { + check_empty( + r#" + fn foo() { + if true {} + $0 + } +"#, + expect![[r#" + kw unsafe + kw fn + kw const + kw type + kw impl + kw extern + kw use + kw trait + kw static + kw mod + kw match + kw while + kw while let + kw loop + kw if + kw if let + kw for + kw true + kw false + kw let + kw else + kw else if + kw return + sn pd + sn ppd + kw self + kw super + kw crate + fn foo() fn() + bt u32 + "#]], + ) +} + +#[test] +fn complete_in_match_arm() { + check_empty( + r#" + fn foo() { + match () { + () => $0 + } + } +"#, + expect![[r#" + kw unsafe + kw match + kw while + kw while let + kw loop + kw if + kw if let + kw for + kw true + kw false + kw return + kw self + kw super + kw crate + fn foo() fn() + bt u32 + "#]], + ) +} + +#[test] +fn completes_in_loop_ctx() { + check_empty( + r"fn my() { loop { $0 } }", + expect![[r#" + kw unsafe + kw fn + kw const + kw type + kw impl + kw extern + kw use + kw trait + kw static + kw mod + kw match + kw while + kw while let + kw loop + kw if + kw if let + kw for + kw true + kw false + kw let + kw continue + kw break + kw return + sn pd + sn ppd + kw self + kw super + kw crate + fn my() fn() + bt u32 + "#]], + ); +} + +#[test] +fn completes_in_let_initializer() { + check_empty( + r#"fn main() { let _ = $0 }"#, + expect![[r#" + kw unsafe + kw match + kw while + kw while let + kw loop + kw if + kw if let + kw for + kw true + kw false + kw return + kw self + kw super + kw crate + fn main() fn() + bt u32 + "#]], + ) +} + +#[test] +fn struct_initializer_field_expr() { + check_empty( + r#" +struct Foo { + pub f: i32, +} +fn foo() { + Foo { + f: $0 + } +} +"#, + expect![[r#" + kw unsafe + kw match + kw while + kw while let + kw loop + kw if + kw if let + kw for + kw true + kw false + kw return + kw self + kw super + kw crate + st Foo + fn foo() fn() + bt u32 + "#]], + ); +} + #[test] fn shadowing_shows_single_completion() { cov_mark::check!(shadowing_shows_single_completion); diff --git a/crates/ide_completion/src/tests/flyimport.rs b/crates/ide_completion/src/tests/flyimport.rs new file mode 100644 index 000000000000..201443e10c2f --- /dev/null +++ b/crates/ide_completion/src/tests/flyimport.rs @@ -0,0 +1,1014 @@ +use expect_test::{expect, Expect}; + +use crate::tests::{check_edit, check_edit_with_config, TEST_CONFIG}; + +fn check(ra_fixture: &str, expect: Expect) { + let config = TEST_CONFIG; + let (db, position) = crate::tests::position(ra_fixture); + let ctx = crate::context::CompletionContext::new(&db, position, &config).unwrap(); + + let mut acc = crate::completions::Completions::default(); + crate::completions::flyimport::import_on_the_fly(&mut acc, &ctx); + + expect.assert_eq(&super::render_completion_list(Vec::from(acc))); +} + +#[test] +fn function_fuzzy_completion() { + check_edit( + "stdin", + r#" +//- /lib.rs crate:dep +pub mod io { + pub fn stdin() {} +}; + +//- /main.rs crate:main deps:dep +fn main() { + stdi$0 +} +"#, + r#" +use dep::io::stdin; + +fn main() { + stdin()$0 +} +"#, + ); +} + +#[test] +fn macro_fuzzy_completion() { + check_edit( + "macro_with_curlies!", + r#" +//- /lib.rs crate:dep +/// Please call me as macro_with_curlies! {} +#[macro_export] +macro_rules! macro_with_curlies { + () => {} +} + +//- /main.rs crate:main deps:dep +fn main() { + curli$0 +} +"#, + r#" +use dep::macro_with_curlies; + +fn main() { + macro_with_curlies! {$0} +} +"#, + ); +} + +#[test] +fn struct_fuzzy_completion() { + check_edit( + "ThirdStruct", + r#" +//- /lib.rs crate:dep +pub struct FirstStruct; +pub mod some_module { + pub struct SecondStruct; + pub struct ThirdStruct; +} + +//- /main.rs crate:main deps:dep +use dep::{FirstStruct, some_module::SecondStruct}; + +fn main() { + this$0 +} +"#, + r#" +use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}}; + +fn main() { + ThirdStruct +} +"#, + ); +} + +#[test] +fn short_paths_are_ignored() { + cov_mark::check!(ignore_short_input_for_path); + + check( + r#" +//- /lib.rs crate:dep +pub struct FirstStruct; +pub mod some_module { + pub struct SecondStruct; + pub struct ThirdStruct; +} + +//- /main.rs crate:main deps:dep +use dep::{FirstStruct, some_module::SecondStruct}; + +fn main() { + t$0 +} +"#, + expect![[r#""#]], + ); +} + +#[test] +fn fuzzy_completions_come_in_specific_order() { + cov_mark::check!(certain_fuzzy_order_test); + check( + r#" +//- /lib.rs crate:dep +pub struct FirstStruct; +pub mod some_module { + // already imported, omitted + pub struct SecondStruct; + // does not contain all letters from the query, omitted + pub struct UnrelatedOne; + // contains all letters from the query, but not in sequence, displayed last + pub struct ThiiiiiirdStruct; + // contains all letters from the query, but not in the beginning, displayed second + pub struct AfterThirdStruct; + // contains all letters from the query in the begginning, displayed first + pub struct ThirdStruct; +} + +//- /main.rs crate:main deps:dep +use dep::{FirstStruct, some_module::SecondStruct}; + +fn main() { + hir$0 +} +"#, + expect![[r#" + st ThirdStruct (use dep::some_module::ThirdStruct) + st AfterThirdStruct (use dep::some_module::AfterThirdStruct) + st ThiiiiiirdStruct (use dep::some_module::ThiiiiiirdStruct) + "#]], + ); +} + +#[test] +fn trait_function_fuzzy_completion() { + let fixture = r#" + //- /lib.rs crate:dep + pub mod test_mod { + pub trait TestTrait { + const SPECIAL_CONST: u8; + type HumbleType; + fn weird_function(); + fn random_method(&self); + } + pub struct TestStruct {} + impl TestTrait for TestStruct { + const SPECIAL_CONST: u8 = 42; + type HumbleType = (); + fn weird_function() {} + fn random_method(&self) {} + } + } + + //- /main.rs crate:main deps:dep + fn main() { + dep::test_mod::TestStruct::wei$0 + } + "#; + + check( + fixture, + expect![[r#" + fn weird_function() (use dep::test_mod::TestTrait) fn() + "#]], + ); + + check_edit( + "weird_function", + fixture, + r#" +use dep::test_mod::TestTrait; + +fn main() { + dep::test_mod::TestStruct::weird_function()$0 +} +"#, + ); +} + +#[test] +fn trait_const_fuzzy_completion() { + let fixture = r#" + //- /lib.rs crate:dep + pub mod test_mod { + pub trait TestTrait { + const SPECIAL_CONST: u8; + type HumbleType; + fn weird_function(); + fn random_method(&self); + } + pub struct TestStruct {} + impl TestTrait for TestStruct { + const SPECIAL_CONST: u8 = 42; + type HumbleType = (); + fn weird_function() {} + fn random_method(&self) {} + } + } + + //- /main.rs crate:main deps:dep + fn main() { + dep::test_mod::TestStruct::spe$0 + } + "#; + + check( + fixture, + expect![[r#" + ct SPECIAL_CONST (use dep::test_mod::TestTrait) + "#]], + ); + + check_edit( + "SPECIAL_CONST", + fixture, + r#" +use dep::test_mod::TestTrait; + +fn main() { + dep::test_mod::TestStruct::SPECIAL_CONST +} +"#, + ); +} + +#[test] +fn trait_method_fuzzy_completion() { + let fixture = r#" + //- /lib.rs crate:dep + pub mod test_mod { + pub trait TestTrait { + const SPECIAL_CONST: u8; + type HumbleType; + fn weird_function(); + fn random_method(&self); + } + pub struct TestStruct {} + impl TestTrait for TestStruct { + const SPECIAL_CONST: u8 = 42; + type HumbleType = (); + fn weird_function() {} + fn random_method(&self) {} + } + } + + //- /main.rs crate:main deps:dep + fn main() { + let test_struct = dep::test_mod::TestStruct {}; + test_struct.ran$0 + } + "#; + + check( + fixture, + expect![[r#" + me random_method() (use dep::test_mod::TestTrait) fn(&self) + "#]], + ); + + check_edit( + "random_method", + fixture, + r#" +use dep::test_mod::TestTrait; + +fn main() { + let test_struct = dep::test_mod::TestStruct {}; + test_struct.random_method()$0 +} +"#, + ); +} + +#[test] +fn no_trait_type_fuzzy_completion() { + check( + r#" +//- /lib.rs crate:dep +pub mod test_mod { + pub trait TestTrait { + const SPECIAL_CONST: u8; + type HumbleType; + fn weird_function(); + fn random_method(&self); + } + pub struct TestStruct {} + impl TestTrait for TestStruct { + const SPECIAL_CONST: u8 = 42; + type HumbleType = (); + fn weird_function() {} + fn random_method(&self) {} + } +} + +//- /main.rs crate:main deps:dep +fn main() { + dep::test_mod::TestStruct::hum$0 +} +"#, + expect![[r#""#]], + ); +} + +#[test] +fn does_not_propose_names_in_scope() { + check( + r#" +//- /lib.rs crate:dep +pub mod test_mod { + pub trait TestTrait { + const SPECIAL_CONST: u8; + type HumbleType; + fn weird_function(); + fn random_method(&self); + } + pub struct TestStruct {} + impl TestTrait for TestStruct { + const SPECIAL_CONST: u8 = 42; + type HumbleType = (); + fn weird_function() {} + fn random_method(&self) {} + } +} + +//- /main.rs crate:main deps:dep +use dep::test_mod::TestStruct; +fn main() { + TestSt$0 +} +"#, + expect![[r#""#]], + ); +} + +#[test] +fn does_not_propose_traits_in_scope() { + check( + r#" +//- /lib.rs crate:dep +pub mod test_mod { + pub trait TestTrait { + const SPECIAL_CONST: u8; + type HumbleType; + fn weird_function(); + fn random_method(&self); + } + pub struct TestStruct {} + impl TestTrait for TestStruct { + const SPECIAL_CONST: u8 = 42; + type HumbleType = (); + fn weird_function() {} + fn random_method(&self) {} + } +} + +//- /main.rs crate:main deps:dep +use dep::test_mod::{TestStruct, TestTrait}; +fn main() { + dep::test_mod::TestStruct::hum$0 +} +"#, + expect![[r#""#]], + ); +} + +#[test] +fn blanket_trait_impl_import() { + check_edit( + "another_function", + r#" +//- /lib.rs crate:dep +pub mod test_mod { + pub struct TestStruct {} + pub trait TestTrait { + fn another_function(); + } + impl TestTrait for T { + fn another_function() {} + } +} + +//- /main.rs crate:main deps:dep +fn main() { + dep::test_mod::TestStruct::ano$0 +} +"#, + r#" +use dep::test_mod::TestTrait; + +fn main() { + dep::test_mod::TestStruct::another_function()$0 +} +"#, + ); +} + +#[test] +fn zero_input_deprecated_assoc_item_completion() { + check( + r#" +//- /lib.rs crate:dep +pub mod test_mod { + #[deprecated] + pub trait TestTrait { + const SPECIAL_CONST: u8; + type HumbleType; + fn weird_function(); + fn random_method(&self); + } + pub struct TestStruct {} + impl TestTrait for TestStruct { + const SPECIAL_CONST: u8 = 42; + type HumbleType = (); + fn weird_function() {} + fn random_method(&self) {} + } +} + +//- /main.rs crate:main deps:dep +fn main() { + let test_struct = dep::test_mod::TestStruct {}; + test_struct.$0 +} + "#, + expect![[r#" + me random_method() (use dep::test_mod::TestTrait) fn(&self) DEPRECATED + "#]], + ); + + check( + r#" +//- /lib.rs crate:dep +pub mod test_mod { + #[deprecated] + pub trait TestTrait { + const SPECIAL_CONST: u8; + type HumbleType; + fn weird_function(); + fn random_method(&self); + } + pub struct TestStruct {} + impl TestTrait for TestStruct { + const SPECIAL_CONST: u8 = 42; + type HumbleType = (); + fn weird_function() {} + fn random_method(&self) {} + } +} + +//- /main.rs crate:main deps:dep +fn main() { + dep::test_mod::TestStruct::$0 +} +"#, + expect![[r#" + fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED + ct SPECIAL_CONST (use dep::test_mod::TestTrait) DEPRECATED + "#]], + ); +} + +#[test] +fn no_completions_in_use_statements() { + check( + r#" +//- /lib.rs crate:dep +pub mod io { + pub fn stdin() {} +}; + +//- /main.rs crate:main deps:dep +use stdi$0 + +fn main() {} +"#, + expect![[]], + ); +} + +#[test] +fn prefix_config_usage() { + let fixture = r#" +mod foo { + pub mod bar { + pub struct Item; + } +} + +use crate::foo::bar; + +fn main() { + Ite$0 +}"#; + let mut config = TEST_CONFIG; + + config.insert_use.prefix_kind = hir::PrefixKind::ByCrate; + check_edit_with_config( + config.clone(), + "Item", + fixture, + r#" +mod foo { + pub mod bar { + pub struct Item; + } +} + +use crate::foo::bar::{self, Item}; + +fn main() { + Item +}"#, + ); + + config.insert_use.prefix_kind = hir::PrefixKind::BySelf; + check_edit_with_config( + config.clone(), + "Item", + fixture, + r#" +mod foo { + pub mod bar { + pub struct Item; + } +} + +use crate::foo::bar; + +use self::foo::bar::Item; + +fn main() { + Item +}"#, + ); + + config.insert_use.prefix_kind = hir::PrefixKind::Plain; + check_edit_with_config( + config, + "Item", + fixture, + r#" +mod foo { + pub mod bar { + pub struct Item; + } +} + +use foo::bar::Item; + +use crate::foo::bar; + +fn main() { + Item +}"#, + ); +} + +#[test] +fn unresolved_qualifier() { + let fixture = r#" +mod foo { + pub mod bar { + pub mod baz { + pub struct Item; + } + } +} + +fn main() { + bar::baz::Ite$0 +}"#; + + check( + fixture, + expect![[r#" + st Item (use foo::bar::baz::Item) + "#]], + ); + + check_edit( + "Item", + fixture, + r#" + use foo::bar; + + mod foo { + pub mod bar { + pub mod baz { + pub struct Item; + } + } + } + + fn main() { + bar::baz::Item + }"#, + ); +} + +#[test] +fn unresolved_assoc_item_container() { + let fixture = r#" +mod foo { + pub struct Item; + + impl Item { + pub const TEST_ASSOC: usize = 3; + } +} + +fn main() { + Item::TEST_A$0 +}"#; + + check( + fixture, + expect![[r#" + ct TEST_ASSOC (use foo::Item) + "#]], + ); + + check_edit( + "TEST_ASSOC", + fixture, + r#" +use foo::Item; + +mod foo { + pub struct Item; + + impl Item { + pub const TEST_ASSOC: usize = 3; + } +} + +fn main() { + Item::TEST_ASSOC +}"#, + ); +} + +#[test] +fn unresolved_assoc_item_container_with_path() { + let fixture = r#" +mod foo { + pub mod bar { + pub struct Item; + + impl Item { + pub const TEST_ASSOC: usize = 3; + } + } +} + +fn main() { + bar::Item::TEST_A$0 +}"#; + + check( + fixture, + expect![[r#" + ct TEST_ASSOC (use foo::bar::Item) + "#]], + ); + + check_edit( + "TEST_ASSOC", + fixture, + r#" +use foo::bar; + +mod foo { + pub mod bar { + pub struct Item; + + impl Item { + pub const TEST_ASSOC: usize = 3; + } + } +} + +fn main() { + bar::Item::TEST_ASSOC +}"#, + ); +} + +#[test] +fn fuzzy_unresolved_path() { + check( + r#" +mod foo { + pub mod bar { + pub struct Item; + + impl Item { + pub const TEST_ASSOC: usize = 3; + } + } +} + +fn main() { + bar::ASS$0 +}"#, + expect![[]], + ) +} + +#[test] +fn unqualified_assoc_items_are_omitted() { + check( + r#" +mod something { + pub trait BaseTrait { + fn test_function() -> i32; + } + + pub struct Item1; + pub struct Item2; + + impl BaseTrait for Item1 { + fn test_function() -> i32 { + 1 + } + } + + impl BaseTrait for Item2 { + fn test_function() -> i32 { + 2 + } + } +} + +fn main() { + test_f$0 +}"#, + expect![[]], + ) +} + +#[test] +fn case_matters() { + check( + r#" +mod foo { + pub const TEST_CONST: usize = 3; + pub fn test_function() -> i32 { + 4 + } +} + +fn main() { + TE$0 +}"#, + expect![[r#" + ct TEST_CONST (use foo::TEST_CONST) + "#]], + ); + + check( + r#" +mod foo { + pub const TEST_CONST: usize = 3; + pub fn test_function() -> i32 { + 4 + } +} + +fn main() { + te$0 +}"#, + expect![[r#" + ct TEST_CONST (use foo::TEST_CONST) + fn test_function() (use foo::test_function) fn() -> i32 + "#]], + ); + + check( + r#" +mod foo { + pub const TEST_CONST: usize = 3; + pub fn test_function() -> i32 { + 4 + } +} + +fn main() { + Te$0 +}"#, + expect![[]], + ); +} + +#[test] +fn no_fuzzy_during_fields_of_record_lit_syntax() { + check( + r#" +mod m { + pub fn some_fn() -> i32 { + 42 + } +} +struct Foo { + some_field: i32, +} +fn main() { + let _ = Foo { so$0 }; +} +"#, + expect![[]], + ); +} + +#[test] +fn fuzzy_after_fields_of_record_lit_syntax() { + check( + r#" +mod m { + pub fn some_fn() -> i32 { + 42 + } +} +struct Foo { + some_field: i32, +} +fn main() { + let _ = Foo { some_field: so$0 }; +} +"#, + expect![[r#" + fn some_fn() (use m::some_fn) fn() -> i32 + "#]], + ); +} + +#[test] +fn no_flyimports_in_traits_and_impl_declarations() { + check( + r#" +mod m { + pub fn some_fn() -> i32 { + 42 + } +} +trait Foo { + som$0 +} +"#, + expect![[r#""#]], + ); + + check( + r#" +mod m { + pub fn some_fn() -> i32 { + 42 + } +} +struct Foo; +impl Foo { + som$0 +} +"#, + expect![[r#""#]], + ); + + check( + r#" +mod m { + pub fn some_fn() -> i32 { + 42 + } +} +struct Foo; +trait Bar {} +impl Bar for Foo { + som$0 +} +"#, + expect![[r#""#]], + ); +} + +#[test] +fn no_inherent_candidates_proposed() { + check( + r#" +mod baz { + pub trait DefDatabase { + fn method1(&self); + } + pub trait HirDatabase: DefDatabase { + fn method2(&self); + } +} + +mod bar { + fn test(db: &dyn crate::baz::HirDatabase) { + db.metho$0 + } +} + "#, + expect![[r#""#]], + ); +} + +#[test] +fn respects_doc_hidden() { + check( + r#" +//- /lib.rs crate:lib deps:dep +fn f() { + ().fro$0 +} + +//- /dep.rs crate:dep +#[doc(hidden)] +pub trait Private { + fn frob(&self) {} +} + +impl Private for T {} + "#, + expect![[r#""#]], + ); + check( + r#" +//- /lib.rs crate:lib deps:dep +fn f() { + ().fro$0 +} + +//- /dep.rs crate:dep +pub trait Private { + #[doc(hidden)] + fn frob(&self) {} +} + +impl Private for T {} + "#, + expect![[r#""#]], + ); +} + +#[test] +fn regression_9760() { + check( + r#" +struct Struct; +fn main() {} + +mod mud { + fn func() { + let struct_instance = Stru$0 + } +} +"#, + expect![[r#" + st Struct (use crate::Struct) + "#]], + ); +} + +#[test] +fn flyimport_pattern() { + check( + r#" +mod module { + pub struct Struct; +} +fn function() { + let Str$0 +} +"#, + expect![[r#" + st Struct (use module::Struct) + "#]], + ); +} + +#[test] +fn flyimport_rename() { + check( + r#" +mod module { + pub struct Struct; +} +use self as Str$0; + "#, + expect![[r#""#]], + ); +} diff --git a/crates/ide_completion/src/tests/record.rs b/crates/ide_completion/src/tests/record.rs index 30b1f2c1c976..e09e99aad5e7 100644 --- a/crates/ide_completion/src/tests/record.rs +++ b/crates/ide_completion/src/tests/record.rs @@ -9,6 +9,7 @@ fn check(ra_fixture: &str, expect: Expect) { #[test] fn without_default_impl() { + cov_mark::check!(no_keyword_completion_in_record_lit); check( r#" struct Struct { foo: u32, bar: usize } diff --git a/crates/rust-analyzer/tests/slow-tests/tidy.rs b/crates/rust-analyzer/tests/slow-tests/tidy.rs index 9be9f3afeaf1..5debb9fb3d19 100644 --- a/crates/rust-analyzer/tests/slow-tests/tidy.rs +++ b/crates/rust-analyzer/tests/slow-tests/tidy.rs @@ -313,6 +313,7 @@ fn check_dbg(path: &Path, text: &str) { "handlers/remove_dbg.rs", // We have .dbg postfix "ide_completion/src/completions/postfix.rs", + "ide_completion/src/completions/keyword.rs", "ide_completion/src/tests/proc_macros.rs", // The documentation in string literals may contain anything for its own purposes "ide_completion/src/lib.rs", From 0468b11de7cbd2ad5d311597d9cfaabdedfab9cd Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 27 Oct 2021 17:18:42 +0200 Subject: [PATCH 2/2] Remove `CompletionKind` in favor of `CompletionItemKind` --- crates/ide_completion/src/completions.rs | 9 +- .../src/completions/attribute.rs | 8 +- .../src/completions/attribute/cfg.rs | 10 +- .../src/completions/attribute/derive.rs | 6 +- .../src/completions/attribute/lint.rs | 8 +- .../src/completions/attribute/repr.rs | 5 +- crates/ide_completion/src/completions/dot.rs | 362 +----------------- .../src/completions/fn_param.rs | 6 +- .../ide_completion/src/completions/keyword.rs | 5 +- crates/ide_completion/src/completions/mod_.rs | 5 +- .../ide_completion/src/completions/postfix.rs | 18 +- .../ide_completion/src/completions/record.rs | 16 +- .../ide_completion/src/completions/snippet.rs | 6 +- .../src/completions/trait_impl.rs | 33 +- crates/ide_completion/src/item.rs | 41 +- crates/ide_completion/src/lib.rs | 2 +- crates/ide_completion/src/render.rs | 169 ++++---- crates/ide_completion/src/render/const_.rs | 10 +- .../ide_completion/src/render/enum_variant.rs | 7 +- crates/ide_completion/src/render/function.rs | 8 +- crates/ide_completion/src/render/macro_.rs | 7 +- crates/ide_completion/src/render/pattern.rs | 8 +- .../src/render/struct_literal.rs | 10 +- .../ide_completion/src/render/type_alias.rs | 10 +- crates/ide_completion/src/tests.rs | 16 +- crates/rust-analyzer/src/to_proto.rs | 2 +- 26 files changed, 191 insertions(+), 596 deletions(-) diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs index 5f751d83a83b..3e658c6e91d8 100644 --- a/crates/ide_completion/src/completions.rs +++ b/crates/ide_completion/src/completions.rs @@ -21,7 +21,7 @@ use hir::known; use ide_db::SymbolKind; use crate::{ - item::{Builder, CompletionKind}, + item::Builder, render::{ const_::render_const, enum_variant::render_variant, @@ -76,8 +76,7 @@ impl Completions { } pub(crate) fn add_keyword(&mut self, ctx: &CompletionContext, keyword: &'static str) { - let mut item = CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), keyword); - item.kind(CompletionItemKind::Keyword); + let item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), keyword); item.add_to(self); } @@ -191,9 +190,7 @@ impl Completions { } pub(crate) fn add_static_lifetime(&mut self, ctx: &CompletionContext) { - let mut item = - CompletionItem::new(CompletionKind::Reference, ctx.source_range(), "'static"); - item.kind(CompletionItemKind::SymbolKind(SymbolKind::LifetimeParam)); + let item = CompletionItem::new(SymbolKind::LifetimeParam, ctx.source_range(), "'static"); self.add(item.build()); } diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs index 119572923c96..2482418ae6a1 100644 --- a/crates/ide_completion/src/completions/attribute.rs +++ b/crates/ide_completion/src/completions/attribute.rs @@ -12,7 +12,7 @@ use syntax::{algo::non_trivia_sibling, ast, AstNode, Direction, SyntaxKind, T}; use crate::{ context::CompletionContext, - item::{CompletionItem, CompletionItemKind, CompletionKind}, + item::{CompletionItem, CompletionItemKind}, Completions, }; @@ -69,11 +69,10 @@ fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attrib let add_completion = |attr_completion: &AttrCompletion| { let mut item = CompletionItem::new( - CompletionKind::Attribute, + CompletionItemKind::Attribute, ctx.source_range(), attr_completion.label, ); - item.kind(CompletionItemKind::Attribute); if let Some(lookup) = attr_completion.lookup { item.lookup_by(lookup); @@ -103,11 +102,10 @@ fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attrib if let hir::ScopeDef::MacroDef(mac) = scope_def { if mac.kind() == hir::MacroKind::Attr { let mut item = CompletionItem::new( - CompletionKind::Attribute, + CompletionItemKind::Attribute, ctx.source_range(), name.to_string(), ); - item.kind(CompletionItemKind::Attribute); if let Some(docs) = mac.docs(ctx.sema.db) { item.documentation(docs); } diff --git a/crates/ide_completion/src/completions/attribute/cfg.rs b/crates/ide_completion/src/completions/attribute/cfg.rs index 171babc698e8..c83e1718ece4 100644 --- a/crates/ide_completion/src/completions/attribute/cfg.rs +++ b/crates/ide_completion/src/completions/attribute/cfg.rs @@ -5,16 +5,14 @@ use std::iter; use syntax::SyntaxKind; use crate::{ - completions::Completions, context::CompletionContext, item::CompletionKind, CompletionItem, - CompletionItemKind, + completions::Completions, context::CompletionContext, CompletionItem, CompletionItemKind, }; pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext) { let add_completion = |item: &str| { let mut completion = - CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), item); + CompletionItem::new(CompletionItemKind::Attribute, ctx.source_range(), item); completion.insert_text(format!(r#""{}""#, item)); - completion.kind(CompletionItemKind::Attribute); acc.add(completion.build()); }; @@ -35,7 +33,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext) { if let Some(krate) = ctx.krate { krate.potential_cfg(ctx.db).get_cfg_values(&name).iter().for_each(|s| { let mut item = CompletionItem::new( - CompletionKind::Attribute, + CompletionItemKind::Attribute, ctx.source_range(), s.as_str(), ); @@ -49,7 +47,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext) { if let Some(krate) = ctx.krate { krate.potential_cfg(ctx.db).get_cfg_keys().iter().for_each(|s| { let item = CompletionItem::new( - CompletionKind::Attribute, + CompletionItemKind::Attribute, ctx.source_range(), s.as_str(), ); diff --git a/crates/ide_completion/src/completions/attribute/derive.rs b/crates/ide_completion/src/completions/attribute/derive.rs index e460a91102ce..7f050f25c9b1 100644 --- a/crates/ide_completion/src/completions/attribute/derive.rs +++ b/crates/ide_completion/src/completions/attribute/derive.rs @@ -7,7 +7,7 @@ use syntax::ast; use crate::{ context::CompletionContext, - item::{CompletionItem, CompletionItemKind, CompletionKind}, + item::{CompletionItem, CompletionItemKind}, Completions, }; @@ -56,8 +56,8 @@ pub(super) fn complete_derive( _ => (&*name, None), }; - let mut item = CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label); - item.kind(CompletionItemKind::Attribute); + let mut item = + CompletionItem::new(CompletionItemKind::Attribute, ctx.source_range(), label); if let Some(docs) = mac.docs(ctx.db) { item.documentation(docs); } diff --git a/crates/ide_completion/src/completions/attribute/lint.rs b/crates/ide_completion/src/completions/attribute/lint.rs index 18942f8beb34..05a29dd0ae21 100644 --- a/crates/ide_completion/src/completions/attribute/lint.rs +++ b/crates/ide_completion/src/completions/attribute/lint.rs @@ -4,7 +4,7 @@ use syntax::{ast, T}; use crate::{ context::CompletionContext, - item::{CompletionItem, CompletionItemKind, CompletionKind}, + item::{CompletionItem, CompletionItemKind}, Completions, }; @@ -58,9 +58,9 @@ pub(super) fn complete_lint( Some(qual) if !is_qualified => format!("{}::{}", qual, name), _ => name.to_owned(), }; - let mut item = CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label); - item.kind(CompletionItemKind::Attribute) - .documentation(hir::Documentation::new(description.to_owned())); + let mut item = + CompletionItem::new(CompletionItemKind::Attribute, ctx.source_range(), label); + item.documentation(hir::Documentation::new(description.to_owned())); item.add_to(acc) } } diff --git a/crates/ide_completion/src/completions/attribute/repr.rs b/crates/ide_completion/src/completions/attribute/repr.rs index 9a12b8571c73..c240912f023d 100644 --- a/crates/ide_completion/src/completions/attribute/repr.rs +++ b/crates/ide_completion/src/completions/attribute/repr.rs @@ -4,7 +4,7 @@ use syntax::ast; use crate::{ context::CompletionContext, - item::{CompletionItem, CompletionItemKind, CompletionKind}, + item::{CompletionItem, CompletionItemKind}, Completions, }; @@ -30,8 +30,7 @@ pub(super) fn complete_repr(acc: &mut Completions, ctx: &CompletionContext, inpu } let mut item = - CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label); - item.kind(CompletionItemKind::Attribute); + CompletionItem::new(CompletionItemKind::Attribute, ctx.source_range(), label); if let Some(lookup) = lookup { item.lookup_by(lookup); } diff --git a/crates/ide_completion/src/completions/dot.rs b/crates/ide_completion/src/completions/dot.rs index 9649667bd76b..ce964e986b07 100644 --- a/crates/ide_completion/src/completions/dot.rs +++ b/crates/ide_completion/src/completions/dot.rs @@ -119,18 +119,6 @@ fn foo(s: S) { s.$0 } expect![[r#" fd foo u32 me bar() fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); } @@ -147,18 +135,6 @@ impl S { expect![[r#" fd the_field (u32,) me foo() fn(self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ) } @@ -175,18 +151,6 @@ impl A { expect![[r#" fd the_field (u32, i32) me foo() fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ) } @@ -199,18 +163,7 @@ impl A { struct A { the_field: u32 } fn foo(a: A) { a.$0() } "#, - expect![[r#" - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - "#]], + expect![[r#""#]], ); } @@ -235,18 +188,6 @@ fn foo(a: lib::m::A) { a.$0 } fd pub_field u32 fd crate_field u32 fd super_field u32 - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); @@ -266,18 +207,6 @@ fn foo(a: lib::m::A) { a.$0 } "#, expect![[r#" fd pub_field u32 - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); @@ -294,19 +223,7 @@ pub mod m { fn foo(a: lib::m::A) { a.$0 } "#, expect![[r#" - fd 1 f64 - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut + fd 1 f64 "#]], ); @@ -328,18 +245,6 @@ fn foo(a: lib::A) { a.$0 } me private_method() fn(&self) me crate_method() fn(&self) me pub_method() fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); check( @@ -358,18 +263,6 @@ fn foo(a: lib::A) { a.$0 } "#, expect![[r#" me pub_method() fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); } @@ -397,18 +290,6 @@ impl A { expect![[r#" fd pub_field u32 me pub_method() fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ) } @@ -423,18 +304,6 @@ fn foo(u: U) { u.$0 } expect![[r#" fd field u8 fd other u16 - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); } @@ -454,18 +323,6 @@ fn foo(a: A) { a.$0 } "#, expect![[r#" me the_method() fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ) } @@ -481,18 +338,6 @@ fn foo(a: A) { a.$0 } "#, expect![[r#" me the_method() (as Trait) fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); check_edit( @@ -523,18 +368,6 @@ fn foo(a: &A) { a.$0 } ", expect![[r#" me the_method() (as Trait) fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); } @@ -553,18 +386,6 @@ fn foo(a: A) { a.$0 } ", expect![[r#" me the_method() (as Trait) fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); } @@ -581,20 +402,7 @@ fn foo(a: A) { a.$0 } "#, - expect![[r#" - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut - "#]], + expect![[r#""#]], ); } @@ -608,20 +416,8 @@ fn foo() { } "#, expect![[r#" - fd 0 i32 - fd 1 f64 - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut + fd 0 i32 + fd 1 f64 "#]], ); } @@ -637,20 +433,8 @@ fn foo() { } "#, expect![[r#" - fd 0 i32 - fd 1 f64 - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut + fd 0 i32 + fd 1 f64 "#]], ); } @@ -673,18 +457,6 @@ impl T { "#, expect![[r#" me blah() fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); } @@ -700,18 +472,6 @@ const X: u32 = { "#, expect![[r#" fd the_field u32 - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); } @@ -728,16 +488,6 @@ fn foo(a: A) { "#, expect![[r#" fd the_field u32 - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) "#]], ); } @@ -755,16 +505,6 @@ fn foo(a: A) { "#, expect![[r#" fd the_field u32 - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) "#]], ); } @@ -781,16 +521,6 @@ fn foo(a: A) { "#, expect![[r#" fd the_field u32 - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) "#]], ); } @@ -817,16 +547,6 @@ fn foo(a: A) { "#, expect![[r#" fd the_field u32 - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) "#]], ); } @@ -846,18 +566,6 @@ fn foo() { "#, expect![[r#" me the_method() fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); } @@ -873,18 +581,6 @@ fn main() { make_s!().f$0; } "#, expect![[r#" me foo() fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ) } @@ -913,18 +609,6 @@ mod foo { "#, expect![[r#" me private() fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ); } @@ -952,16 +636,6 @@ impl S { "#, expect![[r#" me foo() fn(&self) -> &[u8] - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) "#]], ); } @@ -1019,16 +693,6 @@ fn f() { "#, expect![[r#" me method() fn(&self) - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) "#]], ); } @@ -1051,18 +715,6 @@ fn main() { "#, expect![[r#" me into_iter() (as IntoIterator) fn(self) -> ::IntoIter - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut "#]], ) } diff --git a/crates/ide_completion/src/completions/fn_param.rs b/crates/ide_completion/src/completions/fn_param.rs index a9f1944e2836..e910c1daaada 100644 --- a/crates/ide_completion/src/completions/fn_param.rs +++ b/crates/ide_completion/src/completions/fn_param.rs @@ -8,7 +8,7 @@ use syntax::{ use crate::{ context::{ParamKind, PatternContext}, - CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, + CompletionContext, CompletionItem, CompletionItemKind, Completions, }; /// Complete repeated parameters, both name and type. For example, if all @@ -75,7 +75,7 @@ fn add_new_item_to_acc( label: String, lookup: String, ) { - let mut item = CompletionItem::new(CompletionKind::Magic, ctx.source_range(), label); - item.kind(CompletionItemKind::Binding).lookup_by(lookup); + let mut item = CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), label); + item.lookup_by(lookup); item.add_to(acc) } diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index 4fd622f39955..afb8df291168 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs @@ -6,7 +6,7 @@ use syntax::{SyntaxKind, T}; use crate::{ context::PathCompletionContext, patterns::ImmediateLocation, CompletionContext, CompletionItem, - CompletionItemKind, CompletionKind, Completions, + CompletionItemKind, Completions, }; pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) { @@ -158,8 +158,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte } fn add_keyword(ctx: &CompletionContext, acc: &mut Completions, kw: &str, snippet: &str) { - let mut item = CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), kw); - item.kind(CompletionItemKind::Keyword); + let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw); match ctx.config.snippet_cap { Some(cap) => { diff --git a/crates/ide_completion/src/completions/mod_.rs b/crates/ide_completion/src/completions/mod_.rs index c26fa42d1b6b..28be83f196ad 100644 --- a/crates/ide_completion/src/completions/mod_.rs +++ b/crates/ide_completion/src/completions/mod_.rs @@ -11,7 +11,7 @@ use rustc_hash::FxHashSet; use crate::{patterns::ImmediateLocation, CompletionItem}; -use crate::{context::CompletionContext, item::CompletionKind, Completions}; +use crate::{context::CompletionContext, Completions}; /// Complete mod declaration, i.e. `mod $0 ;` pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { @@ -80,8 +80,7 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op if mod_under_caret.semicolon_token().is_none() { label.push(';'); } - let mut item = CompletionItem::new(CompletionKind::Magic, ctx.source_range(), &label); - item.kind(SymbolKind::Module); + let item = CompletionItem::new(SymbolKind::Module, ctx.source_range(), &label); item.add_to(acc) }); diff --git a/crates/ide_completion/src/completions/postfix.rs b/crates/ide_completion/src/completions/postfix.rs index 87b5d6c4720c..4ee257ab43ae 100644 --- a/crates/ide_completion/src/completions/postfix.rs +++ b/crates/ide_completion/src/completions/postfix.rs @@ -15,11 +15,9 @@ use syntax::{ use text_edit::TextEdit; use crate::{ - completions::postfix::format_like::add_format_like_completions, - context::CompletionContext, - item::{Builder, CompletionKind}, - patterns::ImmediateLocation, - CompletionItem, CompletionItemKind, CompletionRelevance, Completions, SnippetScope, + completions::postfix::format_like::add_format_like_completions, context::CompletionContext, + item::Builder, patterns::ImmediateLocation, CompletionItem, CompletionItemKind, + CompletionRelevance, Completions, SnippetScope, }; pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { @@ -45,8 +43,9 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { // Suggest .await syntax for types that implement Future trait if receiver_ty.impls_future(ctx.db) { - let mut item = CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await"); - item.kind(CompletionItemKind::Keyword).detail("expr.await"); + let mut item = + CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), "await"); + item.detail("expr.await"); item.add_to(acc); } @@ -224,8 +223,9 @@ fn build_postfix_snippet_builder<'ctx>( ) -> impl Fn(&str, &str, &str) -> Builder + 'ctx { move |label, detail, snippet| { let edit = TextEdit::replace(delete_range, snippet.to_string()); - let mut item = CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label); - item.detail(detail).kind(CompletionItemKind::Snippet).snippet_edit(cap, edit); + let mut item = + CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), label); + item.detail(detail).snippet_edit(cap, edit); if ctx.original_token.text() == label { let relevance = CompletionRelevance { exact_postfix_snippet_match: true, ..Default::default() }; diff --git a/crates/ide_completion/src/completions/record.rs b/crates/ide_completion/src/completions/record.rs index 80132c2566ae..f0c81f66bc8d 100644 --- a/crates/ide_completion/src/completions/record.rs +++ b/crates/ide_completion/src/completions/record.rs @@ -3,8 +3,7 @@ use ide_db::{helpers::FamousDefs, SymbolKind}; use syntax::{ast::Expr, T}; use crate::{ - item::CompletionKind, patterns::ImmediateLocation, CompletionContext, CompletionItem, - CompletionItemKind, Completions, + patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind, Completions, }; pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { @@ -22,20 +21,17 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> let missing_fields = ctx.sema.record_literal_missing_fields(record_expr); if impl_default_trait && !missing_fields.is_empty() && ctx.path_qual().is_none() { let completion_text = "..Default::default()"; - let mut item = CompletionItem::new( - CompletionKind::Snippet, - ctx.source_range(), - completion_text, - ); + let mut item = + CompletionItem::new(SymbolKind::Field, ctx.source_range(), completion_text); let completion_text = completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text); - item.insert_text(completion_text).kind(SymbolKind::Field); + item.insert_text(completion_text); item.add_to(acc); } if ctx.previous_token_is(T![.]) { let mut item = - CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), ".."); - item.insert_text(".").kind(CompletionItemKind::Snippet); + CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), ".."); + item.insert_text("."); item.add_to(acc); return None; } diff --git a/crates/ide_completion/src/completions/snippet.rs b/crates/ide_completion/src/completions/snippet.rs index a0e5f56129e2..1840e780edf8 100644 --- a/crates/ide_completion/src/completions/snippet.rs +++ b/crates/ide_completion/src/completions/snippet.rs @@ -6,12 +6,12 @@ use syntax::T; use crate::{ context::PathCompletionContext, item::Builder, CompletionContext, CompletionItem, - CompletionItemKind, CompletionKind, Completions, SnippetScope, + CompletionItemKind, Completions, SnippetScope, }; fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder { - let mut item = CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), label); - item.insert_snippet(cap, snippet).kind(CompletionItemKind::Snippet); + let mut item = CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), label); + item.insert_snippet(cap, snippet); item } diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs index 37fa001e0cd0..fc6ef5839c89 100644 --- a/crates/ide_completion/src/completions/trait_impl.rs +++ b/crates/ide_completion/src/completions/trait_impl.rs @@ -40,7 +40,7 @@ use syntax::{ }; use text_edit::TextEdit; -use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions}; +use crate::{CompletionContext, CompletionItem, CompletionItemKind, Completions}; #[derive(Debug, PartialEq, Eq)] enum ImplCompletionKind { @@ -141,14 +141,14 @@ fn add_function_impl( format!("fn {}(..)", fn_name) }; - let mut item = CompletionItem::new(CompletionKind::Magic, ctx.source_range(), label); - item.lookup_by(fn_name).set_documentation(func.docs(ctx.db)); - let completion_kind = if func.self_param(ctx.db).is_some() { CompletionItemKind::Method } else { CompletionItemKind::SymbolKind(SymbolKind::Function) }; + let mut item = CompletionItem::new(completion_kind, ctx.source_range(), label); + item.lookup_by(fn_name).set_documentation(func.docs(ctx.db)); + let range = replacement_range(ctx, fn_def_node); if let Some(source) = func.source(ctx.db) { @@ -170,7 +170,6 @@ fn add_function_impl( item.text_edit(TextEdit::replace(range, header)); } }; - item.kind(completion_kind); item.add_to(acc); } } @@ -211,10 +210,9 @@ fn add_type_alias_impl( let snippet = format!("type {} = ", alias_name); let range = replacement_range(ctx, type_def_node); - let mut item = CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone()); + let mut item = CompletionItem::new(SymbolKind::TypeAlias, ctx.source_range(), snippet.clone()); item.text_edit(TextEdit::replace(range, snippet)) .lookup_by(alias_name) - .kind(SymbolKind::TypeAlias) .set_documentation(type_alias.docs(ctx.db)); item.add_to(acc); } @@ -241,10 +239,9 @@ fn add_const_impl( let range = replacement_range(ctx, const_def_node); let mut item = - CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone()); + CompletionItem::new(SymbolKind::Const, ctx.source_range(), snippet.clone()); item.text_edit(TextEdit::replace(range, snippet)) .lookup_by(const_name) - .kind(SymbolKind::Const) .set_documentation(const_.docs(ctx.db)); item.add_to(acc); } @@ -358,23 +355,7 @@ impl Test for T { } } ", - expect![[r#" - sn if if expr {} - sn while while expr {} - sn not !expr - sn ref &expr - sn refm &mut expr - sn match match expr {} - sn box Box::new(expr) - sn ok Ok(expr) - sn err Err(expr) - sn some Some(expr) - sn dbg dbg!(expr) - sn dbgr dbg!(&expr) - sn call function(expr) - sn let let - sn letm let mut - "#]], + expect![[r#""#]], ); check( diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs index a9eec472caf6..3f0accfbe17f 100644 --- a/crates/ide_completion/src/item.rs +++ b/crates/ide_completion/src/item.rs @@ -21,10 +21,6 @@ use text_edit::TextEdit; /// `CompletionItem`, use `new` method and the `Builder` struct. #[derive(Clone)] pub struct CompletionItem { - /// Used only internally in tests, to check only specific kind of - /// completion (postfix, keyword, reference, etc). - #[allow(unused)] - pub(crate) completion_kind: CompletionKind, /// Label in the completion pop up which identifies completion. label: String, /// Range of identifier that is being completed. @@ -43,7 +39,7 @@ pub struct CompletionItem { is_snippet: bool, /// What item (struct, function, etc) are we completing. - kind: Option, + kind: CompletionItemKind, /// Lookup is used to check if completion item indeed can complete current /// ident. @@ -92,9 +88,7 @@ impl fmt::Debug for CompletionItem { } else { s.field("text_edit", &self.text_edit); } - if let Some(kind) = self.kind().as_ref() { - s.field("kind", kind); - } + s.field("kind", &self.kind()); if self.lookup() != self.label() { s.field("lookup", &self.lookup()); } @@ -270,32 +264,15 @@ impl CompletionItemKind { } } -// FIXME remove this? -/// Like [`CompletionItemKind`] but solely used for filtering test results. -#[derive(Debug, PartialEq, Eq, Copy, Clone)] -pub(crate) enum CompletionKind { - /// Parser-based keyword completion. - Keyword, - /// Your usual "complete all valid identifiers". - Reference, - /// "Secret sauce" completions. - Magic, - Snippet, - Postfix, - BuiltinType, - Attribute, -} - impl CompletionItem { pub(crate) fn new( - completion_kind: CompletionKind, + kind: impl Into, source_range: TextRange, label: impl Into, ) -> Builder { let label = label.into(); Builder { source_range, - completion_kind, label, insert_text: None, is_snippet: false, @@ -303,7 +280,7 @@ impl CompletionItem { detail: None, documentation: None, lookup: None, - kind: None, + kind: kind.into(), text_edit: None, deprecated: false, trigger_call_info: None, @@ -342,7 +319,7 @@ impl CompletionItem { self.lookup.as_deref().unwrap_or(&self.label) } - pub fn kind(&self) -> Option { + pub fn kind(&self) -> CompletionItemKind { self.kind } @@ -401,7 +378,6 @@ impl ImportEdit { #[derive(Clone)] pub(crate) struct Builder { source_range: TextRange, - completion_kind: CompletionKind, imports_to_add: SmallVec<[ImportEdit; 1]>, trait_name: Option, label: String, @@ -410,7 +386,7 @@ pub(crate) struct Builder { detail: Option, documentation: Option, lookup: Option, - kind: Option, + kind: CompletionItemKind, text_edit: Option, deprecated: bool, trigger_call_info: Option, @@ -454,7 +430,6 @@ impl Builder { documentation: self.documentation, lookup, kind: self.kind, - completion_kind: self.completion_kind, deprecated: self.deprecated, trigger_call_info: self.trigger_call_info.unwrap_or(false), relevance: self.relevance, @@ -487,10 +462,6 @@ impl Builder { self.is_snippet = true; self.insert_text(snippet) } - pub(crate) fn kind(&mut self, kind: impl Into) -> &mut Builder { - self.kind = Some(kind.into()); - self - } pub(crate) fn text_edit(&mut self, edit: TextEdit) -> &mut Builder { self.text_edit = Some(edit); self diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs index 6680e66c6062..d555eff878c7 100644 --- a/crates/ide_completion/src/lib.rs +++ b/crates/ide_completion/src/lib.rs @@ -24,7 +24,7 @@ use ide_db::{ use syntax::algo; use text_edit::TextEdit; -use crate::{completions::Completions, context::CompletionContext, item::CompletionKind}; +use crate::{completions::Completions, context::CompletionContext}; pub use crate::{ config::CompletionConfig, diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs index 58443f566ef5..4180d704a308 100644 --- a/crates/ide_completion/src/render.rs +++ b/crates/ide_completion/src/render.rs @@ -22,7 +22,7 @@ use crate::{ context::{PathCompletionContext, PathKind}, item::{CompletionRelevanceTypeMatch, ImportEdit}, render::{enum_variant::render_variant, function::render_fn, macro_::render_macro}, - CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, CompletionRelevance, + CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance, }; /// Interface for data and methods required for items rendering. #[derive(Debug)] @@ -85,7 +85,7 @@ pub(crate) fn render_field( let is_deprecated = ctx.is_deprecated(field); let name = field.name(ctx.db()).to_string(); let mut item = CompletionItem::new( - CompletionKind::Reference, + SymbolKind::Field, ctx.source_range(), receiver.map_or_else(|| name.clone(), |receiver| format!("{}.{}", receiver, name)), ); @@ -94,8 +94,7 @@ pub(crate) fn render_field( exact_name_match: compute_exact_name_match(ctx.completion, name.as_str()), ..CompletionRelevance::default() }); - item.kind(SymbolKind::Field) - .detail(ty.display(ctx.db()).to_string()) + item.detail(ty.display(ctx.db()).to_string()) .set_documentation(field.docs(ctx.db())) .set_deprecated(is_deprecated) .lookup_by(name.as_str()); @@ -118,13 +117,11 @@ pub(crate) fn render_tuple_field( ty: &hir::Type, ) -> CompletionItem { let mut item = CompletionItem::new( - CompletionKind::Reference, + SymbolKind::Field, ctx.source_range(), receiver.map_or_else(|| field.to_string(), |receiver| format!("{}.{}", receiver, field)), ); - item.kind(SymbolKind::Field) - .detail(ty.display(ctx.db()).to_string()) - .lookup_by(field.to_string()); + item.detail(ty.display(ctx.db()).to_string()).lookup_by(field.to_string()); item.build() } @@ -147,10 +144,7 @@ pub(crate) fn render_resolution_with_import( hir::ScopeDef::ModuleDef(hir::ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db), _ => item_name(ctx.db(), import_edit.import.original_item)?, }; - render_resolution_(ctx, local_name, Some(import_edit), &resolution).map(|mut item| { - item.completion_kind = CompletionKind::Magic; - item - }) + render_resolution_(ctx, local_name, Some(import_edit), &resolution) } fn render_resolution_( @@ -162,11 +156,6 @@ fn render_resolution_( let _p = profile::span("render_resolution"); use hir::ModuleDef::*; - let completion_kind = match resolution { - hir::ScopeDef::ModuleDef(BuiltinType(..)) => CompletionKind::BuiltinType, - _ => CompletionKind::Reference, - }; - let kind = match resolution { hir::ScopeDef::ModuleDef(Function(func)) => { return render_fn(ctx, import_to_add, Some(local_name), *func); @@ -208,11 +197,10 @@ fn render_resolution_( } hir::ScopeDef::Unknown => { let mut item = CompletionItem::new( - CompletionKind::Reference, + CompletionItemKind::UnresolvedReference, ctx.source_range(), local_name.to_string(), ); - item.kind(CompletionItemKind::UnresolvedReference); if let Some(import_to_add) = import_to_add { item.add_import(import_to_add); } @@ -221,7 +209,7 @@ fn render_resolution_( }; let local_name = local_name.to_string(); - let mut item = CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone()); + let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.clone()); if let hir::ScopeDef::Local(local) = resolution { let ty = local.ty(ctx.db()); if !ty.is_unknown() { @@ -260,8 +248,7 @@ fn render_resolution_( } } } - item.kind(kind) - .set_documentation(scope_def_docs(ctx.db(), resolution)) + item.set_documentation(scope_def_docs(ctx.db(), resolution)) .set_deprecated(scope_def_is_deprecated(&ctx, resolution)); if let Some(import_to_add) = import_to_add { @@ -344,37 +331,54 @@ mod tests { use std::cmp; use expect_test::{expect, Expect}; + use ide_db::SymbolKind; use itertools::Itertools; use crate::{ item::CompletionRelevanceTypeMatch, tests::{check_edit, do_completion, get_all_items, TEST_CONFIG}, - CompletionKind, CompletionRelevance, + CompletionItem, CompletionItemKind, CompletionRelevance, }; #[track_caller] - fn check(ra_fixture: &str, expect: Expect) { - let actual = do_completion(ra_fixture, CompletionKind::Reference); + fn check(ra_fixture: &str, kind: impl Into, expect: Expect) { + let actual = do_completion(ra_fixture, kind.into()); expect.assert_debug_eq(&actual); } #[track_caller] - fn check_relevance(ra_fixture: &str, expect: Expect) { - check_relevance_for_kinds(&[CompletionKind::Reference], ra_fixture, expect) + fn check_kinds(ra_fixture: &str, kinds: &[CompletionItemKind], expect: Expect) { + let actual: Vec<_> = + kinds.iter().flat_map(|&kind| do_completion(ra_fixture, kind)).collect(); + expect.assert_debug_eq(&actual); } #[track_caller] - fn check_relevance_for_kinds(kinds: &[CompletionKind], ra_fixture: &str, expect: Expect) { + fn check_relevance_for_kinds(ra_fixture: &str, kinds: &[CompletionItemKind], expect: Expect) { let mut actual = get_all_items(TEST_CONFIG, ra_fixture); - actual.retain(|it| kinds.contains(&it.completion_kind)); + actual.retain(|it| kinds.contains(&it.kind())); actual.sort_by_key(|it| cmp::Reverse(it.relevance().score())); + check_relevance_(actual, expect); + } + #[track_caller] + fn check_relevance(ra_fixture: &str, expect: Expect) { + let mut actual = get_all_items(TEST_CONFIG, ra_fixture); + actual.retain(|it| it.kind() != CompletionItemKind::Snippet); + actual.retain(|it| it.kind() != CompletionItemKind::Keyword); + actual.retain(|it| it.kind() != CompletionItemKind::BuiltinType); + actual.sort_by_key(|it| cmp::Reverse(it.relevance().score())); + check_relevance_(actual, expect); + } + + #[track_caller] + fn check_relevance_(actual: Vec, expect: Expect) { let actual = actual .into_iter() .flat_map(|it| { let mut items = vec![]; - let tag = it.kind().unwrap().tag(); + let tag = it.kind().tag(); let relevance = display_relevance(it.relevance()); items.push(format!("{} {} {}\n", tag, it.label(), relevance)); @@ -418,6 +422,7 @@ enum Foo { Foo { x: i32, y: i32 } } fn main() { Foo::Fo$0 } "#, + SymbolKind::Variant, expect![[r#" [ CompletionItem { @@ -443,6 +448,7 @@ enum Foo { Foo (i32, i32) } fn main() { Foo::Fo$0 } "#, + SymbolKind::Variant, expect![[r#" [ CompletionItem { @@ -470,6 +476,7 @@ fn foo(a: u32, b: u32, t: T) -> (u32, T) { (a, t) } fn main() { fo$0 } "#, + SymbolKind::Function, expect![[r#" [ CompletionItem { @@ -508,6 +515,7 @@ enum Foo { Foo } fn main() { Foo::Fo$0 } "#, + SymbolKind::Variant, expect![[r#" [ CompletionItem { @@ -527,15 +535,40 @@ fn main() { Foo::Fo$0 } #[test] fn lookup_enums_by_two_qualifiers() { - check( + check_kinds( r#" mod m { pub enum Spam { Foo, Bar(i32) } } fn main() { let _: m::Spam = S$0 } "#, + &[ + CompletionItemKind::SymbolKind(SymbolKind::Function), + CompletionItemKind::SymbolKind(SymbolKind::Module), + CompletionItemKind::SymbolKind(SymbolKind::Variant), + ], expect![[r#" [ + CompletionItem { + label: "main()", + source_range: 75..76, + delete: 75..76, + insert: "main()$0", + kind: SymbolKind( + Function, + ), + lookup: "main", + detail: "fn()", + }, + CompletionItem { + label: "m", + source_range: 75..76, + delete: 75..76, + insert: "m", + kind: SymbolKind( + Module, + ), + }, CompletionItem { label: "Spam::Bar(…)", source_range: 75..76, @@ -556,15 +589,6 @@ fn main() { let _: m::Spam = S$0 } }, trigger_call_info: true, }, - CompletionItem { - label: "m", - source_range: 75..76, - delete: 75..76, - insert: "m", - kind: SymbolKind( - Module, - ), - }, CompletionItem { label: "m::Spam::Foo", source_range: 75..76, @@ -584,17 +608,6 @@ fn main() { let _: m::Spam = S$0 } exact_postfix_snippet_match: false, }, }, - CompletionItem { - label: "main()", - source_range: 75..76, - delete: 75..76, - insert: "main()$0", - kind: SymbolKind( - Function, - ), - lookup: "main", - detail: "fn()", - }, ] "#]], ) @@ -611,6 +624,7 @@ fn something_else_deprecated() {} fn main() { som$0 } "#, + SymbolKind::Function, expect![[r#" [ CompletionItem { @@ -657,6 +671,7 @@ fn main() { som$0 } struct A { #[deprecated] the_field: u32 } fn foo() { A { the$0 } } "#, + SymbolKind::Field, expect![[r#" [ CompletionItem { @@ -685,7 +700,7 @@ fn foo() { A { the$0 } } #[test] fn renders_docs() { - check( + check_kinds( r#" struct S { /// Field docs @@ -695,6 +710,7 @@ impl S { /// Method docs fn bar(self) { self.$0 } }"#, + &[CompletionItemKind::Method, CompletionItemKind::SymbolKind(SymbolKind::Field)], expect![[r#" [ CompletionItem { @@ -726,7 +742,7 @@ impl S { "#]], ); - check( + check_kinds( r#" use self::my$0; @@ -740,18 +756,23 @@ enum E { } use self::E::*; "#, + &[ + CompletionItemKind::SymbolKind(SymbolKind::Module), + CompletionItemKind::SymbolKind(SymbolKind::Variant), + CompletionItemKind::SymbolKind(SymbolKind::Enum), + ], expect![[r#" [ CompletionItem { - label: "E", + label: "my", source_range: 10..12, delete: 10..12, - insert: "E", + insert: "my", kind: SymbolKind( - Enum, + Module, ), documentation: Documentation( - "enum docs", + "mod docs", ), }, CompletionItem { @@ -768,15 +789,15 @@ use self::E::*; ), }, CompletionItem { - label: "my", + label: "E", source_range: 10..12, delete: 10..12, - insert: "my", + insert: "E", kind: SymbolKind( - Module, + Enum, ), documentation: Documentation( - "mod docs", + "enum docs", ), }, ] @@ -795,6 +816,7 @@ impl S { } fn foo(s: S) { s.$0 } "#, + CompletionItemKind::Method, expect![[r#" [ CompletionItem { @@ -1318,18 +1340,28 @@ fn main() { #[test] fn struct_field_method_ref() { - check( + check_kinds( r#" struct Foo { bar: u32 } impl Foo { fn baz(&self) -> u32 { 0 } } fn foo(f: Foo) { let _: &u32 = f.b$0 } "#, + &[CompletionItemKind::Method, CompletionItemKind::SymbolKind(SymbolKind::Field)], // FIXME // Ideally we'd also suggest &f.bar and &f.baz() as exact // type matches. See #8058. expect![[r#" [ + CompletionItem { + label: "baz()", + source_range: 98..99, + delete: 98..99, + insert: "baz()$0", + kind: Method, + lookup: "baz", + detail: "fn(&self) -> u32", + }, CompletionItem { label: "bar", source_range: 98..99, @@ -1340,15 +1372,6 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 } ), detail: "u32", }, - CompletionItem { - label: "baz()", - source_range: 98..99, - delete: 98..99, - insert: "baz()$0", - kind: Method, - lookup: "baz", - detail: "fn(&self) -> u32", - }, ] "#]], ); @@ -1387,7 +1410,6 @@ fn foo() { #[test] fn postfix_completion_relevance() { check_relevance_for_kinds( - &[CompletionKind::Postfix, CompletionKind::Magic], r#" mod ops { pub trait Not { @@ -1404,7 +1426,8 @@ mod ops { fn main() { let _: bool = (9 > 2).not$0; } -"#, + "#, + &[CompletionItemKind::Snippet, CompletionItemKind::Method], expect![[r#" sn not [snippet] me not() (use ops::Not) [type_could_unify] diff --git a/crates/ide_completion/src/render/const_.rs b/crates/ide_completion/src/render/const_.rs index 166ae3c16bc5..241e0043c9c5 100644 --- a/crates/ide_completion/src/render/const_.rs +++ b/crates/ide_completion/src/render/const_.rs @@ -7,10 +7,7 @@ use syntax::{ display::const_label, }; -use crate::{ - item::{CompletionItem, CompletionKind}, - render::RenderContext, -}; +use crate::{item::CompletionItem, render::RenderContext}; pub(crate) fn render_const(ctx: RenderContext<'_>, const_: hir::Const) -> Option { ConstRender::new(ctx, const_)?.render() @@ -34,9 +31,8 @@ impl<'a> ConstRender<'a> { let detail = self.detail(); let mut item = - CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), name.clone()); - item.kind(SymbolKind::Const) - .set_documentation(self.ctx.docs(self.const_)) + CompletionItem::new(SymbolKind::Const, self.ctx.source_range(), name.clone()); + item.set_documentation(self.ctx.docs(self.const_)) .set_deprecated( self.ctx.is_deprecated(self.const_) || self.ctx.is_deprecated_assoc_item(self.const_), diff --git a/crates/ide_completion/src/render/enum_variant.rs b/crates/ide_completion/src/render/enum_variant.rs index 95768713cf56..728e0e2a174b 100644 --- a/crates/ide_completion/src/render/enum_variant.rs +++ b/crates/ide_completion/src/render/enum_variant.rs @@ -7,7 +7,7 @@ use ide_db::SymbolKind; use itertools::Itertools; use crate::{ - item::{CompletionItem, CompletionKind, ImportEdit}, + item::{CompletionItem, ImportEdit}, render::{builder_ext::Params, compute_ref_match, compute_type_match, RenderContext}, CompletionRelevance, }; @@ -61,12 +61,11 @@ impl<'a> EnumRender<'a> { } fn render(self, import_to_add: Option) -> CompletionItem { let mut item = CompletionItem::new( - CompletionKind::Reference, + SymbolKind::Variant, self.ctx.source_range(), self.qualified_name.to_string(), ); - item.kind(SymbolKind::Variant) - .set_documentation(self.variant.docs(self.ctx.db())) + item.set_documentation(self.variant.docs(self.ctx.db())) .set_deprecated(self.ctx.is_deprecated(self.variant)) .detail(self.detail()); diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs index 769a0ed21f53..7515bb6d47db 100644 --- a/crates/ide_completion/src/render/function.rs +++ b/crates/ide_completion/src/render/function.rs @@ -7,7 +7,7 @@ use itertools::Itertools; use syntax::ast; use crate::{ - item::{CompletionItem, CompletionItemKind, CompletionKind, CompletionRelevance, ImportEdit}, + item::{CompletionItem, CompletionItemKind, CompletionRelevance, ImportEdit}, render::{ builder_ext::Params, compute_exact_name_match, compute_ref_match, compute_type_match, RenderContext, @@ -79,10 +79,8 @@ impl<'a> FunctionRender<'a> { Some(receiver) => format!("{}.{}", receiver, &self.name), None => self.name.clone(), }; - let mut item = - CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), call.clone()); - item.kind(self.kind()) - .set_documentation(self.ctx.docs(self.func)) + let mut item = CompletionItem::new(self.kind(), self.ctx.source_range(), call.clone()); + item.set_documentation(self.ctx.docs(self.func)) .set_deprecated( self.ctx.is_deprecated(self.func) || self.ctx.is_deprecated_assoc_item(self.func), ) diff --git a/crates/ide_completion/src/render/macro_.rs b/crates/ide_completion/src/render/macro_.rs index 196b667baacd..b1ddfab0cbbf 100644 --- a/crates/ide_completion/src/render/macro_.rs +++ b/crates/ide_completion/src/render/macro_.rs @@ -6,7 +6,7 @@ use syntax::display::macro_label; use crate::{ context::CallKind, - item::{CompletionItem, CompletionKind, ImportEdit}, + item::{CompletionItem, ImportEdit}, render::RenderContext, }; @@ -47,9 +47,8 @@ impl<'a> MacroRender<'a> { } else { Some(self.ctx.source_range()) }?; - let mut item = CompletionItem::new(CompletionKind::Reference, source_range, &self.label()); - item.kind(SymbolKind::Macro) - .set_documentation(self.docs.clone()) + let mut item = CompletionItem::new(SymbolKind::Macro, source_range, &self.label()); + item.set_documentation(self.docs.clone()) .set_deprecated(self.ctx.is_deprecated(self.macro_)) .set_detail(self.detail()); diff --git a/crates/ide_completion/src/render/pattern.rs b/crates/ide_completion/src/render/pattern.rs index 521296fd9b72..b7032806204a 100644 --- a/crates/ide_completion/src/render/pattern.rs +++ b/crates/ide_completion/src/render/pattern.rs @@ -6,7 +6,6 @@ use itertools::Itertools; use crate::{ context::{ParamKind, PatternContext}, - item::CompletionKind, render::RenderContext, CompletionItem, CompletionItemKind, }; @@ -58,11 +57,8 @@ fn build_completion( pat: String, def: impl HasAttrs + Copy, ) -> CompletionItem { - let mut item = CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), name); - item.kind(CompletionItemKind::Binding) - .set_documentation(ctx.docs(def)) - .set_deprecated(ctx.is_deprecated(def)) - .detail(&pat); + let mut item = CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), name); + item.set_documentation(ctx.docs(def)).set_deprecated(ctx.is_deprecated(def)).detail(&pat); match ctx.snippet_cap() { Some(snippet_cap) => item.insert_snippet(snippet_cap, pat), None => item.insert_text(pat), diff --git a/crates/ide_completion/src/render/struct_literal.rs b/crates/ide_completion/src/render/struct_literal.rs index 810b51effd38..4eb4f6b9f127 100644 --- a/crates/ide_completion/src/render/struct_literal.rs +++ b/crates/ide_completion/src/render/struct_literal.rs @@ -4,7 +4,7 @@ use hir::{db::HirDatabase, HasAttrs, HasVisibility, Name, StructKind}; use ide_db::helpers::SnippetCap; use itertools::Itertools; -use crate::{item::CompletionKind, render::RenderContext, CompletionItem, CompletionItemKind}; +use crate::{render::RenderContext, CompletionItem, CompletionItemKind}; pub(crate) fn render_struct_literal( ctx: RenderContext<'_>, @@ -33,11 +33,9 @@ fn build_completion( literal: String, def: impl HasAttrs + Copy, ) -> CompletionItem { - let mut item = CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), name + " {…}"); - item.kind(CompletionItemKind::Snippet) - .set_documentation(ctx.docs(def)) - .set_deprecated(ctx.is_deprecated(def)) - .detail(&literal); + let mut item = + CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), name + " {…}"); + item.set_documentation(ctx.docs(def)).set_deprecated(ctx.is_deprecated(def)).detail(&literal); match ctx.snippet_cap() { Some(snippet_cap) => item.insert_snippet(snippet_cap, literal), None => item.insert_text(literal), diff --git a/crates/ide_completion/src/render/type_alias.rs b/crates/ide_completion/src/render/type_alias.rs index c1e61826430d..7b6d2fa5c3ab 100644 --- a/crates/ide_completion/src/render/type_alias.rs +++ b/crates/ide_completion/src/render/type_alias.rs @@ -7,10 +7,7 @@ use syntax::{ display::type_label, }; -use crate::{ - item::{CompletionItem, CompletionKind}, - render::RenderContext, -}; +use crate::{item::CompletionItem, render::RenderContext}; pub(crate) fn render_type_alias( ctx: RenderContext<'_>, @@ -50,9 +47,8 @@ impl<'a> TypeAliasRender<'a> { let detail = self.detail(); let mut item = - CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), name.clone()); - item.kind(SymbolKind::TypeAlias) - .set_documentation(self.ctx.docs(self.type_alias)) + CompletionItem::new(SymbolKind::TypeAlias, self.ctx.source_range(), name.clone()); + item.set_documentation(self.ctx.docs(self.type_alias)) .set_deprecated( self.ctx.is_deprecated(self.type_alias) || self.ctx.is_deprecated_assoc_item(self.type_alias), diff --git a/crates/ide_completion/src/tests.rs b/crates/ide_completion/src/tests.rs index fee61e0bfcf6..f063a9638ca2 100644 --- a/crates/ide_completion/src/tests.rs +++ b/crates/ide_completion/src/tests.rs @@ -38,7 +38,7 @@ use stdx::{format_to, trim_indent}; use syntax::{AstNode, NodeOrToken, SyntaxElement}; use test_utils::assert_eq_text; -use crate::{item::CompletionKind, CompletionConfig, CompletionItem}; +use crate::{CompletionConfig, CompletionItem, CompletionItemKind}; /// Lots of basic item definitions const BASE_ITEMS_FIXTURE: &str = r#" @@ -96,10 +96,10 @@ fn completion_list_with_config( let items = items .into_iter() .filter(|it| { - it.completion_kind != CompletionKind::BuiltinType || !mem::replace(&mut bt_seen, true) + it.kind() != CompletionItemKind::BuiltinType || !mem::replace(&mut bt_seen, true) }) - .filter(|it| include_keywords || it.completion_kind != CompletionKind::Keyword) - .filter(|it| include_keywords || it.completion_kind != CompletionKind::Snippet) + .filter(|it| include_keywords || it.kind() != CompletionItemKind::Keyword) + .filter(|it| include_keywords || it.kind() != CompletionItemKind::Snippet) .collect(); render_completion_list(items) } @@ -115,18 +115,18 @@ pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { (database, FilePosition { file_id, offset }) } -pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec { +pub(crate) fn do_completion(code: &str, kind: CompletionItemKind) -> Vec { do_completion_with_config(TEST_CONFIG, code, kind) } pub(crate) fn do_completion_with_config( config: CompletionConfig, code: &str, - kind: CompletionKind, + kind: CompletionItemKind, ) -> Vec { get_all_items(config, code) .into_iter() - .filter(|c| c.completion_kind == kind) + .filter(|c| c.kind() == kind) .sorted_by(|l, r| l.label().cmp(r.label())) .collect() } @@ -140,7 +140,7 @@ fn render_completion_list(completions: Vec) -> String { completions .into_iter() .map(|it| { - let tag = it.kind().unwrap().tag(); + let tag = it.kind().tag(); let var_name = format!("{} {}", tag, it.label()); let mut buf = var_name; if let Some(detail) = it.detail() { diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index b17711d6a645..473b7a870f40 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -248,7 +248,7 @@ fn completion_item( label: item.label().to_string(), detail: item.detail().map(|it| it.to_string()), filter_text: Some(item.lookup().to_string()), - kind: item.kind().map(completion_item_kind), + kind: Some(completion_item_kind(item.kind())), text_edit: Some(text_edit), additional_text_edits: Some(additional_text_edits), documentation: item.documentation().map(documentation),