From 9df848c58079a710869dcde2692466cc4b0ac78e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 17 Jun 2021 15:10:25 +0200 Subject: Less filtering in completion tests --- crates/ide_completion/src/completions/attribute.rs | 6 +- .../src/completions/attribute/derive.rs | 7 +- .../src/completions/attribute/lint.rs | 1 - crates/ide_completion/src/completions/keyword.rs | 24 ++-- crates/ide_completion/src/completions/lifetime.rs | 14 +-- crates/ide_completion/src/completions/mod_.rs | 134 ++++++++++----------- crates/ide_completion/src/tests.rs | 8 +- 7 files changed, 96 insertions(+), 98 deletions(-) (limited to 'crates/ide_completion/src') diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs index 3866c5917..f3b11e72d 100644 --- a/crates/ide_completion/src/completions/attribute.rs +++ b/crates/ide_completion/src/completions/attribute.rs @@ -322,7 +322,7 @@ mod tests { use expect_test::{expect, Expect}; - use crate::{tests::filtered_completion_list, CompletionKind}; + use crate::tests::completion_list; #[test] fn attributes_are_sorted() { @@ -341,7 +341,7 @@ mod tests { } fn check(ra_fixture: &str, expect: Expect) { - let actual = filtered_completion_list(ra_fixture, CompletionKind::Attribute); + let actual = completion_list(ra_fixture); expect.assert_eq(&actual); } @@ -786,6 +786,7 @@ mod tests { at target_feature = "…" at test at track_caller + kw return "#]], ); } @@ -801,6 +802,7 @@ mod tests { at deny(…) at forbid(…) at warn(…) + kw return "#]], ); } diff --git a/crates/ide_completion/src/completions/attribute/derive.rs b/crates/ide_completion/src/completions/attribute/derive.rs index 5201095e8..6fe41e0d6 100644 --- a/crates/ide_completion/src/completions/attribute/derive.rs +++ b/crates/ide_completion/src/completions/attribute/derive.rs @@ -82,7 +82,7 @@ const DEFAULT_DERIVE_COMPLETIONS: &[DeriveDependencies] = &[ mod tests { use expect_test::{expect, Expect}; - use crate::{tests::filtered_completion_list, CompletionKind}; + use crate::tests::completion_list; fn check(ra_fixture: &str, expect: Expect) { let builtin_derives = r#" @@ -106,10 +106,7 @@ pub macro PartialOrd {} pub macro Ord {} "#; - let actual = filtered_completion_list( - &format!("{} {}", builtin_derives, ra_fixture), - CompletionKind::Attribute, - ); + let actual = completion_list(&format!("{} {}", builtin_derives, ra_fixture)); expect.assert_eq(&actual); } diff --git a/crates/ide_completion/src/completions/attribute/lint.rs b/crates/ide_completion/src/completions/attribute/lint.rs index 4812b075c..1ddc38986 100644 --- a/crates/ide_completion/src/completions/attribute/lint.rs +++ b/crates/ide_completion/src/completions/attribute/lint.rs @@ -33,7 +33,6 @@ pub(super) fn complete_lint( #[cfg(test)] mod tests { - use crate::tests::check_edit; #[test] diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index 9754122a0..af67f9315 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs @@ -37,17 +37,6 @@ pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionC } }; } - - // Suggest .await syntax for types that implement Future trait - if let Some(receiver) = ctx.dot_receiver() { - if let Some(ty) = ctx.sema.type_of_expr(receiver) { - if ty.impls_future(ctx.db) { - let mut item = kw_completion("await"); - item.detail("expr.await"); - item.add_to(acc); - } - }; - } } pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) { @@ -59,6 +48,19 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte cov_mark::hit!(no_keyword_completion_in_record_lit); return; } + + // Suggest .await syntax for types that implement Future trait + if let Some(receiver) = ctx.dot_receiver() { + if let Some(ty) = ctx.sema.type_of_expr(receiver) { + if ty.impls_future(ctx.db) { + let mut item = + CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await"); + item.kind(CompletionItemKind::Keyword).detail("expr.await"); + item.add_to(acc); + } + }; + } + let mut add_keyword = |kw, snippet| add_keyword(ctx, acc, kw, snippet); let expects_assoc_item = ctx.expects_assoc_item(); diff --git a/crates/ide_completion/src/completions/lifetime.rs b/crates/ide_completion/src/completions/lifetime.rs index 36f595164..abf6935c9 100644 --- a/crates/ide_completion/src/completions/lifetime.rs +++ b/crates/ide_completion/src/completions/lifetime.rs @@ -49,19 +49,11 @@ pub(crate) fn complete_label(acc: &mut Completions, ctx: &CompletionContext) { 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}; 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); - expect.assert_eq(&actual) + let actual = completion_list(ra_fixture); + expect.assert_eq(&actual); } #[test] diff --git a/crates/ide_completion/src/completions/mod_.rs b/crates/ide_completion/src/completions/mod_.rs index 5def0d06a..dee3ec88d 100644 --- a/crates/ide_completion/src/completions/mod_.rs +++ b/crates/ide_completion/src/completions/mod_.rs @@ -153,17 +153,17 @@ mod tests { fn lib_module_completion() { check( r#" - //- /lib.rs - mod $0 - //- /foo.rs - fn foo() {} - //- /foo/ignored_foo.rs - fn ignored_foo() {} - //- /bar/mod.rs - fn bar() {} - //- /bar/ignored_bar.rs - fn ignored_bar() {} - "#, +//- /lib.rs +mod $0 +//- /foo.rs +fn foo() {} +//- /foo/ignored_foo.rs +fn ignored_foo() {} +//- /bar/mod.rs +fn bar() {} +//- /bar/ignored_bar.rs +fn ignored_bar() {} +"#, expect![[r#" md foo; md bar; @@ -175,13 +175,13 @@ mod tests { fn no_module_completion_with_module_body() { check( r#" - //- /lib.rs - mod $0 { +//- /lib.rs +mod $0 { - } - //- /foo.rs - fn foo() {} - "#, +} +//- /foo.rs +fn foo() {} +"#, expect![[r#""#]], ); } @@ -190,17 +190,17 @@ mod tests { fn main_module_completion() { check( r#" - //- /main.rs - mod $0 - //- /foo.rs - fn foo() {} - //- /foo/ignored_foo.rs - fn ignored_foo() {} - //- /bar/mod.rs - fn bar() {} - //- /bar/ignored_bar.rs - fn ignored_bar() {} - "#, +//- /main.rs +mod $0 +//- /foo.rs +fn foo() {} +//- /foo/ignored_foo.rs +fn ignored_foo() {} +//- /bar/mod.rs +fn bar() {} +//- /bar/ignored_bar.rs +fn ignored_bar() {} +"#, expect![[r#" md foo; md bar; @@ -212,13 +212,13 @@ mod tests { fn main_test_module_completion() { check( r#" - //- /main.rs - mod tests { - mod $0; - } - //- /tests/foo.rs - fn foo() {} - "#, +//- /main.rs +mod tests { + mod $0; +} +//- /tests/foo.rs +fn foo() {} +"#, expect![[r#" md foo "#]], @@ -229,19 +229,19 @@ mod tests { fn directly_nested_module_completion() { check( r#" - //- /lib.rs - mod foo; - //- /foo.rs - mod $0; - //- /foo/bar.rs - fn bar() {} - //- /foo/bar/ignored_bar.rs - fn ignored_bar() {} - //- /foo/baz/mod.rs - fn baz() {} - //- /foo/moar/ignored_moar.rs - fn ignored_moar() {} - "#, +//- /lib.rs +mod foo; +//- /foo.rs +mod $0; +//- /foo/bar.rs +fn bar() {} +//- /foo/bar/ignored_bar.rs +fn ignored_bar() {} +//- /foo/baz/mod.rs +fn baz() {} +//- /foo/moar/ignored_moar.rs +fn ignored_moar() {} +"#, expect![[r#" md bar md baz @@ -253,15 +253,15 @@ mod tests { fn nested_in_source_module_completion() { check( r#" - //- /lib.rs - mod foo; - //- /foo.rs - mod bar { - mod $0 - } - //- /foo/bar/baz.rs - fn baz() {} - "#, +//- /lib.rs +mod foo; +//- /foo.rs +mod bar { + mod $0 +} +//- /foo/bar/baz.rs +fn baz() {} +"#, expect![[r#" md baz; "#]], @@ -299,16 +299,16 @@ mod tests { fn already_declared_bin_module_completion_omitted() { check( r#" - //- /src/bin.rs crate:main - fn main() {} - //- /src/bin/foo.rs - mod $0 - //- /src/bin/bar.rs - mod foo; - fn bar() {} - //- /src/bin/bar/bar_ignored.rs - fn bar_ignored() {} - "#, +//- /src/bin.rs crate:main +fn main() {} +//- /src/bin/foo.rs +mod $0 +//- /src/bin/bar.rs +mod foo; +fn bar() {} +//- /src/bin/bar/bar_ignored.rs +fn bar_ignored() {} +"#, expect![[r#""#]], ); } diff --git a/crates/ide_completion/src/tests.rs b/crates/ide_completion/src/tests.rs index 89c7fb524..4b7e19cc0 100644 --- a/crates/ide_completion/src/tests.rs +++ b/crates/ide_completion/src/tests.rs @@ -1,3 +1,9 @@ +//! Tests and test utilities for completions. +//! +//! Most tests live in this module or its submodules unless for very specific completions like +//! `attributes` or `lifetimes` where the completed concept is a distinct thing. +//! Notable examples for completions that are being tested in this module's submodule are paths. + mod item_list; mod use_tree; @@ -32,7 +38,7 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig { }, }; -fn completion_list(code: &str) -> String { +pub(crate) fn completion_list(code: &str) -> String { completion_list_with_config(TEST_CONFIG, code) } -- cgit v1.2.3 From a9a77671f2405e0cb65160c17268beec5114e259 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 17 Jun 2021 15:32:34 +0200 Subject: Move item specific completion tests --- crates/ide_completion/src/completions/keyword.rs | 32 ------ crates/ide_completion/src/completions/mod_.rs | 4 +- .../src/completions/qualified_path.rs | 20 ---- .../src/completions/unqualified_path.rs | 17 ---- crates/ide_completion/src/tests.rs | 1 + crates/ide_completion/src/tests/items.rs | 108 +++++++++++++++++++++ 6 files changed, 111 insertions(+), 71 deletions(-) create mode 100644 crates/ide_completion/src/tests/items.rs (limited to 'crates/ide_completion/src') diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index af67f9315..c5cd3c2f7 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs @@ -387,22 +387,6 @@ fn quux() -> i32 { ); } - #[test] - fn test_where_keyword() { - check( - r"trait A $0", - expect![[r#" - kw where - "#]], - ); - check( - r"impl A $0", - expect![[r#" - kw where - "#]], - ); - } - #[test] fn no_keyword_completion_in_comments() { cov_mark::check!(no_keyword_completion_in_comments); @@ -479,22 +463,6 @@ fn foo() { ) } - #[test] - fn before_field() { - check( - r#" -struct Foo { - $0 - pub f: i32, -} -"#, - expect![[r#" - kw pub(crate) - kw pub - "#]], - ) - } - #[test] fn skip_struct_initializer() { cov_mark::check!(no_keyword_completion_in_record_lit); diff --git a/crates/ide_completion/src/completions/mod_.rs b/crates/ide_completion/src/completions/mod_.rs index dee3ec88d..1c864c0e7 100644 --- a/crates/ide_completion/src/completions/mod_.rs +++ b/crates/ide_completion/src/completions/mod_.rs @@ -141,11 +141,11 @@ fn module_chain_to_containing_module_file( #[cfg(test)] mod tests { - use crate::{tests::filtered_completion_list, CompletionKind}; + use crate::tests::completion_list; use expect_test::{expect, Expect}; fn check(ra_fixture: &str, expect: Expect) { - let actual = filtered_completion_list(ra_fixture, CompletionKind::Magic); + 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 0597879ac..88f4d940d 100644 --- a/crates/ide_completion/src/completions/qualified_path.rs +++ b/crates/ide_completion/src/completions/qualified_path.rs @@ -555,26 +555,6 @@ fn f() {m::$0} ); } - #[test] - fn completes_in_assoc_item_list() { - check( - r#" -#[macro_export] -macro_rules! foo { () => {} } -mod bar {} - -struct MyStruct {} -impl MyStruct { - crate::$0 -} -"#, - expect![[r##" - md bar - ma foo!(…) #[macro_export] macro_rules! foo - "##]], - ); - } - #[test] fn completes_reexported_items_under_correct_name() { check( diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs index 6f96eceb9..1864bfbcc 100644 --- a/crates/ide_completion/src/completions/unqualified_path.rs +++ b/crates/ide_completion/src/completions/unqualified_path.rs @@ -712,23 +712,6 @@ fn f() {} ) } - #[test] - fn completes_target_type_or_trait_in_impl_block() { - check( - r#" -trait MyTrait {} -struct MyStruct {} - -impl My$0 -"#, - expect![[r#" - sp Self - tt MyTrait - st MyStruct - "#]], - ) - } - #[test] fn completes_types_and_const_in_arg_list() { check( diff --git a/crates/ide_completion/src/tests.rs b/crates/ide_completion/src/tests.rs index 4b7e19cc0..1ea6017ce 100644 --- a/crates/ide_completion/src/tests.rs +++ b/crates/ide_completion/src/tests.rs @@ -6,6 +6,7 @@ mod item_list; mod use_tree; +mod items; use hir::{PrefixKind, Semantics}; use ide_db::{ diff --git a/crates/ide_completion/src/tests/items.rs b/crates/ide_completion/src/tests/items.rs new file mode 100644 index 000000000..dd4ba3864 --- /dev/null +++ b/crates/ide_completion/src/tests/items.rs @@ -0,0 +1,108 @@ +//! Completions tests for item specifics overall. +//! +//! Except for use items which are tested in [super::use_tree] and mod declarations with are tested +//! in [crate::completions::mod_]. +use expect_test::{expect, Expect}; + +use crate::tests::completion_list; + +fn check(ra_fixture: &str, expect: Expect) { + let base = r#"#[rustc_builtin_macro] +pub macro Clone {} +enum Enum { Variant } +struct Struct {} +#[macro_export] +macro_rules! foo {} +mod bar {} +const CONST: () = (); +trait Trait {} +"#; + let actual = completion_list(&format!("{}{}", base, ra_fixture)); + expect.assert_eq(&actual) +} + +#[test] +fn target_type_or_trait_in_impl_block() { + // FIXME: should not complete `Self` + check( + r#" +impl My$0 +"#, + expect![[r##" + sp Self + tt Trait + en Enum + st Struct + md bar + ma foo!(…) #[macro_export] macro_rules! foo + ma foo!(…) #[macro_export] macro_rules! foo + bt u32 + bt bool + bt u8 + bt isize + bt u16 + bt u64 + bt u128 + bt f32 + bt i128 + bt i16 + bt str + bt i64 + bt char + bt f64 + bt i32 + bt i8 + bt usize + "##]], + ) +} + +#[test] +fn after_trait_name_in_trait_def() { + // FIXME: should only complete `where` + check( + r"trait A $0", + expect![[r##" + kw where + sn tmod (Test module) + sn tfn (Test function) + sn macro_rules + md bar + ma foo!(…) #[macro_export] macro_rules! foo + ma foo!(…) #[macro_export] macro_rules! foo + "##]], + ); +} + +#[test] +fn after_trait_or_target_name_in_impl() { + // FIXME: should only complete `for` and `where` + check( + r"impl A $0", + expect![[r##" + kw where + sn tmod (Test module) + sn tfn (Test function) + sn macro_rules + md bar + ma foo!(…) #[macro_export] macro_rules! foo + ma foo!(…) #[macro_export] macro_rules! foo + "##]], + ); +} + +#[test] +fn before_record_field() { + check( + r#" +struct Foo { + $0 + pub f: i32, +} +"#, + expect![[r#" + kw pub(crate) + kw pub + "#]], + ) +} -- cgit v1.2.3 From 2a48b532208de413e4e5d39e81c33a4644ecaa22 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 17 Jun 2021 15:43:21 +0200 Subject: Correct completions in items tests --- crates/ide_completion/src/completions/keyword.rs | 3 ++ crates/ide_completion/src/completions/snippet.rs | 6 ++- .../src/completions/unqualified_path.rs | 5 +- crates/ide_completion/src/context.rs | 4 ++ crates/ide_completion/src/tests/items.rs | 63 ++++++++++++++-------- 5 files changed, 57 insertions(+), 24 deletions(-) (limited to 'crates/ide_completion/src') diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index c5cd3c2f7..c99fdef05 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs @@ -69,6 +69,9 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte if ctx.has_impl_or_trait_prev_sibling() { add_keyword("where", "where "); + if ctx.has_impl_prev_sibling() { + add_keyword("for", "for "); + } return; } if ctx.previous_token_is(T![unsafe]) { diff --git a/crates/ide_completion/src/completions/snippet.rs b/crates/ide_completion/src/completions/snippet.rs index 81ddfa34f..cbc20cc2c 100644 --- a/crates/ide_completion/src/completions/snippet.rs +++ b/crates/ide_completion/src/completions/snippet.rs @@ -36,7 +36,11 @@ pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionConte } pub(crate) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionContext) { - if !ctx.expects_item() || ctx.previous_token_is(T![unsafe]) || ctx.path_qual().is_some() { + if !ctx.expects_item() + || ctx.previous_token_is(T![unsafe]) + || ctx.path_qual().is_some() + || ctx.has_impl_or_trait_prev_sibling() + { return; } if ctx.has_visibility_prev_sibling() { diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs index 1864bfbcc..8ea5a2d5b 100644 --- a/crates/ide_completion/src/completions/unqualified_path.rs +++ b/crates/ide_completion/src/completions/unqualified_path.rs @@ -6,7 +6,7 @@ use syntax::{ast, AstNode}; use crate::{patterns::ImmediateLocation, CompletionContext, Completions}; pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) { - if ctx.is_path_disallowed() || !ctx.is_trivial_path() { + if ctx.is_path_disallowed() || !ctx.is_trivial_path() || ctx.has_impl_or_trait_prev_sibling() { return; } @@ -68,6 +68,9 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC return; } let add_resolution = match res { + ScopeDef::ImplSelfType(_) => { + !ctx.previous_token_is(syntax::T![impl]) && !ctx.previous_token_is(syntax::T![for]) + } // Don't suggest attribute macros and derives. ScopeDef::MacroDef(mac) => mac.is_fn_like(), // no values in type places diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index 240cac1de..d7a7e9cca 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs @@ -305,6 +305,10 @@ impl<'a> CompletionContext<'a> { ) } + pub(crate) fn has_impl_prev_sibling(&self) -> bool { + matches!(self.prev_sibling, Some(ImmediatePrevSibling::ImplDefType)) + } + pub(crate) fn has_visibility_prev_sibling(&self) -> bool { matches!(self.prev_sibling, Some(ImmediatePrevSibling::Visibility)) } diff --git a/crates/ide_completion/src/tests/items.rs b/crates/ide_completion/src/tests/items.rs index dd4ba3864..8dfb8221b 100644 --- a/crates/ide_completion/src/tests/items.rs +++ b/crates/ide_completion/src/tests/items.rs @@ -23,13 +23,11 @@ trait Trait {} #[test] fn target_type_or_trait_in_impl_block() { - // FIXME: should not complete `Self` check( r#" -impl My$0 +impl Tra$0 "#, expect![[r##" - sp Self tt Trait en Enum st Struct @@ -58,36 +56,57 @@ impl My$0 } #[test] -fn after_trait_name_in_trait_def() { - // FIXME: should only complete `where` +fn target_type_in_trait_impl_block() { check( - r"trait A $0", + r#" +impl Trait for Str$0 +"#, expect![[r##" - kw where - sn tmod (Test module) - sn tfn (Test function) - sn macro_rules + tt Trait + en Enum + st Struct md bar - ma foo!(…) #[macro_export] macro_rules! foo - ma foo!(…) #[macro_export] macro_rules! foo + ma foo!(…) #[macro_export] macro_rules! foo + ma foo!(…) #[macro_export] macro_rules! foo + bt u32 + bt bool + bt u8 + bt isize + bt u16 + bt u64 + bt u128 + bt f32 + bt i128 + bt i16 + bt str + bt i64 + bt char + bt f64 + bt i32 + bt i8 + bt usize "##]], + ) +} + +#[test] +fn after_trait_name_in_trait_def() { + check( + r"trait A $0", + expect![[r#" + kw where + "#]], ); } #[test] fn after_trait_or_target_name_in_impl() { - // FIXME: should only complete `for` and `where` check( - r"impl A $0", - expect![[r##" + r"impl Trait $0", + expect![[r#" kw where - sn tmod (Test module) - sn tfn (Test function) - sn macro_rules - md bar - ma foo!(…) #[macro_export] macro_rules! foo - ma foo!(…) #[macro_export] macro_rules! foo - "##]], + kw for + "#]], ); } -- cgit v1.2.3