From f835279b3ae41644e9568187b4468cd9d9e84eca Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 21 Jun 2021 13:48:25 +0200 Subject: Move out completion pattern tests --- crates/ide_completion/src/completions/keyword.rs | 22 -- crates/ide_completion/src/completions/pattern.rs | 395 --------------------- .../src/completions/unqualified_path.rs | 50 --- crates/ide_completion/src/tests.rs | 1 + crates/ide_completion/src/tests/pattern.rs | 348 ++++++++++++++++++ 5 files changed, 349 insertions(+), 467 deletions(-) create mode 100644 crates/ide_completion/src/tests/pattern.rs (limited to 'crates/ide_completion') diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index 07541c79c..e40ec6280 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs @@ -372,28 +372,6 @@ fn quux() -> i32 { ); } - #[test] - fn test_mut_in_ref_and_in_fn_parameters_list() { - check( - r"fn my_fn(&$0) {}", - expect![[r#" - kw mut - "#]], - ); - check( - r"fn my_fn($0) {}", - expect![[r#" - kw mut - "#]], - ); - check( - r"fn my_fn() { let &$0 }", - expect![[r#" - kw mut - "#]], - ); - } - #[test] fn no_keyword_completion_in_comments() { cov_mark::check!(no_keyword_completion_in_comments); diff --git a/crates/ide_completion/src/completions/pattern.rs b/crates/ide_completion/src/completions/pattern.rs index efe3c957a..bd13a62d7 100644 --- a/crates/ide_completion/src/completions/pattern.rs +++ b/crates/ide_completion/src/completions/pattern.rs @@ -55,398 +55,3 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { } }); } - -#[cfg(test)] -mod tests { - use expect_test::{expect, Expect}; - - use crate::{ - tests::{check_edit, filtered_completion_list}, - CompletionKind, - }; - - fn check(ra_fixture: &str, expect: Expect) { - let actual = filtered_completion_list(ra_fixture, CompletionKind::Reference); - expect.assert_eq(&actual) - } - - fn check_snippet(ra_fixture: &str, expect: Expect) { - let actual = filtered_completion_list(ra_fixture, CompletionKind::Snippet); - expect.assert_eq(&actual) - } - - #[test] - fn completes_enum_variants_and_modules() { - check( - r#" -enum E { X } -use self::E::X; -const Z: E = E::X; -mod m {} - -static FOO: E = E::X; -struct Bar { f: u32 } - -fn foo() { - match E::X { a$0 } -} -"#, - expect![[r#" - en E - ct Z - st Bar - ev X - md m - "#]], - ); - } - - #[test] - fn does_not_complete_non_fn_macros() { - check( - r#" -macro_rules! m { ($e:expr) => { $e } } -enum E { X } - -#[rustc_builtin_macro] -macro Clone {} - -fn foo() { - match E::X { $0 } -} -"#, - expect![[r#" - ev E::X () - en E - ma m!(…) macro_rules! m - "#]], - ); - } - - #[test] - fn completes_in_simple_macro_call() { - check( - r#" -macro_rules! m { ($e:expr) => { $e } } -enum E { X } - -fn foo() { - m!(match E::X { a$0 }) -} -"#, - expect![[r#" - ev E::X () - en E - ma m!(…) macro_rules! m - "#]], - ); - } - - #[test] - fn completes_in_irrefutable_let() { - check( - r#" -enum E { X } -use self::E::X; -const Z: E = E::X; -mod m {} - -static FOO: E = E::X; -struct Bar { f: u32 } - -fn foo() { - let a$0 -} -"#, - expect![[r#" - st Bar - "#]], - ); - } - - #[test] - fn completes_in_param() { - check( - r#" -enum E { X } - -static FOO: E = E::X; -struct Bar { f: u32 } - -fn foo(a$0) { -} -"#, - expect![[r#" - st Bar - "#]], - ); - } - - #[test] - fn completes_pat_in_let() { - check_snippet( - r#" -struct Bar { f: u32 } - -fn foo() { - let a$0 -} -"#, - expect![[r#" - bn Bar Bar { f$1 }$0 - "#]], - ); - } - - #[test] - fn completes_param_pattern() { - check_snippet( - r#" -struct Foo { bar: String, baz: String } -struct Bar(String, String); -struct Baz; -fn outer(a$0) {} -"#, - expect![[r#" - bn Foo Foo { bar$1, baz$2 }: Foo$0 - bn Bar Bar($1, $2): Bar$0 - "#]], - ) - } - - #[test] - fn completes_let_pattern() { - check_snippet( - r#" -struct Foo { bar: String, baz: String } -struct Bar(String, String); -struct Baz; -fn outer() { - let a$0 -} -"#, - expect![[r#" - bn Foo Foo { bar$1, baz$2 }$0 - bn Bar Bar($1, $2)$0 - "#]], - ) - } - - #[test] - fn completes_refutable_pattern() { - check_snippet( - r#" -struct Foo { bar: i32, baz: i32 } -struct Bar(String, String); -struct Baz; -fn outer() { - match () { - a$0 - } -} -"#, - expect![[r#" - bn Foo Foo { bar$1, baz$2 }$0 - bn Bar Bar($1, $2)$0 - "#]], - ) - } - - #[test] - fn omits_private_fields_pat() { - check_snippet( - r#" -mod foo { - pub struct Foo { pub bar: i32, baz: i32 } - pub struct Bar(pub String, String); - pub struct Invisible(String, String); -} -use foo::*; - -fn outer() { - match () { - a$0 - } -} -"#, - expect![[r#" - bn Foo Foo { bar$1, .. }$0 - bn Bar Bar($1, ..)$0 - "#]], - ) - } - - #[test] - fn only_shows_ident_completion() { - check_edit( - "Foo", - r#" -struct Foo(i32); -fn main() { - match Foo(92) { - a$0(92) => (), - } -} -"#, - r#" -struct Foo(i32); -fn main() { - match Foo(92) { - Foo(92) => (), - } -} -"#, - ); - } - - #[test] - fn completes_self_pats() { - check_snippet( - r#" -struct Foo(i32); -impl Foo { - fn foo() { - match () { - a$0 - } - } -} - "#, - expect![[r#" - bn Self Self($1)$0 - bn Foo Foo($1)$0 - "#]], - ) - } - - #[test] - fn completes_qualified_variant() { - check_snippet( - r#" -enum Foo { - Bar { baz: i32 } -} -impl Foo { - fn foo() { - match {Foo::Bar { baz: 0 }} { - B$0 - } - } -} - "#, - expect![[r#" - bn Self::Bar Self::Bar { baz$1 }$0 - bn Foo::Bar Foo::Bar { baz$1 }$0 - "#]], - ) - } - - #[test] - fn completes_enum_variant_matcharm() { - check( - r#" -enum Foo { Bar, Baz, Quux } - -fn main() { - let foo = Foo::Quux; - match foo { Qu$0 } -} -"#, - expect![[r#" - ev Foo::Bar () - ev Foo::Baz () - ev Foo::Quux () - en Foo - "#]], - ) - } - - #[test] - fn completes_enum_variant_matcharm_ref() { - check( - r#" -enum Foo { Bar, Baz, Quux } - -fn main() { - let foo = Foo::Quux; - match &foo { Qu$0 } -} -"#, - expect![[r#" - ev Foo::Bar () - ev Foo::Baz () - ev Foo::Quux () - en Foo - "#]], - ) - } - - #[test] - fn completes_enum_variant_iflet() { - check( - r#" -enum Foo { Bar, Baz, Quux } - -fn main() { - let foo = Foo::Quux; - if let Qu$0 = foo { } -} -"#, - expect![[r#" - ev Foo::Bar () - ev Foo::Baz () - ev Foo::Quux () - en Foo - "#]], - ) - } - - #[test] - fn completes_enum_variant_impl() { - check( - r#" -enum Foo { Bar, Baz, Quux } -impl Foo { - fn foo() { match Foo::Bar { Q$0 } } -} -"#, - expect![[r#" - ev Self::Bar () - ev Self::Baz () - ev Self::Quux () - ev Foo::Bar () - ev Foo::Baz () - ev Foo::Quux () - sp Self - en Foo - "#]], - ) - } - - #[test] - fn completes_in_record_field_pat() { - check_snippet( - r#" -struct Foo { bar: Bar } -struct Bar(u32); -fn outer(Foo { bar: $0 }: Foo) {} -"#, - expect![[r#" - bn Foo Foo { bar$1 }$0 - bn Bar Bar($1)$0 - "#]], - ) - } - - #[test] - fn skips_in_record_field_pat_name() { - check_snippet( - r#" -struct Foo { bar: Bar } -struct Bar(u32); -fn outer(Foo { bar$0 }: Foo) {} -"#, - expect![[r#""#]], - ) - } -} diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs index 81c4fb305..819fa3a43 100644 --- a/crates/ide_completion/src/completions/unqualified_path.rs +++ b/crates/ide_completion/src/completions/unqualified_path.rs @@ -134,56 +134,6 @@ fn foo() { ); } - #[test] - fn bind_pat_and_path_ignore_at() { - check( - r#" -enum Enum { A, B } -fn quux(x: Option) { - match x { - None => (), - Some(en$0 @ Enum::A) => (), - } -} -"#, - expect![[r#""#]], - ); - } - - #[test] - fn bind_pat_and_path_ignore_ref() { - check( - r#" -enum Enum { A, B } -fn quux(x: Option) { - match x { - None => (), - Some(ref en$0) => (), - } -} -"#, - expect![[r#""#]], - ); - } - - #[test] - fn bind_pat_and_path() { - check( - r#" -enum Enum { A, B } -fn quux(x: Option) { - match x { - None => (), - Some(En$0) => (), - } -} -"#, - expect![[r#" - en Enum - "#]], - ); - } - #[test] fn completes_bindings_from_let() { check( diff --git a/crates/ide_completion/src/tests.rs b/crates/ide_completion/src/tests.rs index 211c89c40..7af8c903b 100644 --- a/crates/ide_completion/src/tests.rs +++ b/crates/ide_completion/src/tests.rs @@ -7,6 +7,7 @@ mod item_list; mod use_tree; mod items; +mod pattern; use hir::{PrefixKind, Semantics}; use ide_db::{ diff --git a/crates/ide_completion/src/tests/pattern.rs b/crates/ide_completion/src/tests/pattern.rs new file mode 100644 index 000000000..1ad5ccd97 --- /dev/null +++ b/crates/ide_completion/src/tests/pattern.rs @@ -0,0 +1,348 @@ +//! Completions tests for pattern position. +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) +} + +fn check_with(ra_fixture: &str, expect: Expect) { + let base = r#" +enum Enum { TupleV(u32), RecordV { field: u32 }, UnitV } +use self::Enum::TupleV; +mod module {} + +static STATIC: Unit = Unit; +const CONST: Unit = Unit; +struct Record { field: u32 } +struct Tuple(u32); +struct Unit +macro_rules! makro {} +"#; + let actual = completion_list(&format!("{}\n{}", base, ra_fixture)); + expect.assert_eq(&actual) +} + +#[test] +fn ident_rebind_pat() { + check( + r#" +fn quux() { + let en$0 @ x +} +"#, + expect![[r#" + kw mut + "#]], + ); +} + +#[test] +fn ident_ref_pat() { + check( + r#" +fn quux() { + let ref en$0 +} +"#, + expect![[r#" + kw mut + "#]], + ); + check( + r#" +fn quux() { + let ref en$0 @ x +} +"#, + expect![[r#" + kw mut + "#]], + ); +} + +#[test] +fn ident_ref_mut_pat() { + // FIXME mut is already here, don't complete it again + check( + r#" +fn quux() { + let ref mut en$0 +} +"#, + expect![[r#" + kw mut + "#]], + ); + check( + r#" +fn quux() { + let ref mut en$0 @ x +} +"#, + expect![[r#" + kw mut + "#]], + ); +} + +#[test] +fn ref_pat() { + check( + r#" +fn quux() { + let &en$0 +} +"#, + expect![[r#" + kw mut + "#]], + ); + // FIXME mut is already here, don't complete it again + check( + r#" +fn quux() { + let &mut en$0 +} +"#, + expect![[r#" + kw mut + "#]], + ); +} + +#[test] +fn refutable() { + check_with( + r#" +fn foo() { + if let a$0 +} +"#, + expect![[r#" + kw mut + bn Record Record { field$1 }$0 + st Record + en Enum + bn Tuple Tuple($1)$0 + st Tuple + md module + bn TupleV TupleV($1)$0 + ev TupleV + st Unit + ct CONST + ma makro!(…) macro_rules! makro + "#]], + ); +} + +#[test] +fn irrefutable() { + check_with( + r#" +fn foo() { + let a$0 +} +"#, + expect![[r#" + kw mut + bn Record Record { field$1 }$0 + st Record + bn Tuple Tuple($1)$0 + st Tuple + st Unit + ma makro!(…) macro_rules! makro + "#]], + ); +} + +#[test] +fn in_param() { + check_with( + r#" +fn foo(a$0) { +} +"#, + expect![[r#" + kw mut + bn Record Record { field$1 }: Record$0 + st Record + bn Tuple Tuple($1): Tuple$0 + st Tuple + st Unit + ma makro!(…) macro_rules! makro + "#]], + ); +} + +#[test] +fn only_fn_like_macros() { + check( + r#" +macro_rules! m { ($e:expr) => { $e } } + +#[rustc_builtin_macro] +macro Clone {} + +fn foo() { + let x$0 +} +"#, + expect![[r#" + kw mut + ma m!(…) macro_rules! m + "#]], + ); +} + +#[test] +fn in_simple_macro_call() { + check( + r#" +macro_rules! m { ($e:expr) => { $e } } +enum E { X } + +fn foo() { + m!(match E::X { a$0 }) +} +"#, + expect![[r#" + kw mut + ev E::X () + en E + ma m!(…) macro_rules! m + "#]], + ); +} + +#[test] +fn omits_private_fields_pat() { + check( + r#" +mod foo { + pub struct Record { pub field: i32, _field: i32 } + pub struct Tuple(pub u32, u32); + pub struct Invisible(u32, u32); +} +use foo::*; + +fn outer() { + if let a$0 +} +"#, + expect![[r#" + kw mut + bn Record Record { field$1, .. }$0 + st Record + bn Tuple Tuple($1, ..)$0 + st Tuple + st Invisible + md foo + "#]], + ) +} + +// #[test] +// fn only_shows_ident_completion() { +// check_edit( +// "Foo", +// r#" +// struct Foo(i32); +// fn main() { +// match Foo(92) { +// a$0(92) => (), +// } +// } +// "#, +// r#" +// struct Foo(i32); +// fn main() { +// match Foo(92) { +// Foo(92) => (), +// } +// } +// "#, +// ); +// } + +#[test] +fn completes_self_pats() { + check( + r#" +struct Foo(i32); +impl Foo { + fn foo() { + match Foo(0) { + a$0 + } + } +} + "#, + expect![[r#" + kw mut + bn Self Self($1)$0 + sp Self + bn Foo Foo($1)$0 + st Foo + "#]], + ) +} + +#[test] +fn completes_qualified_variant() { + check( + r#" +enum Foo { + Bar { baz: i32 } +} +impl Foo { + fn foo() { + match {Foo::Bar { baz: 0 }} { + B$0 + } + } +} + "#, + expect![[r#" + kw mut + bn Self::Bar Self::Bar { baz$1 }$0 + ev Self::Bar { baz: i32 } + bn Foo::Bar Foo::Bar { baz$1 }$0 + ev Foo::Bar { baz: i32 } + sp Self + en Foo + "#]], + ) +} + +#[test] +fn completes_in_record_field_pat() { + check( + r#" +struct Foo { bar: Bar } +struct Bar(u32); +fn outer(Foo { bar: $0 }: Foo) {} +"#, + expect![[r#" + kw mut + bn Foo Foo { bar$1 }$0 + st Foo + bn Bar Bar($1)$0 + st Bar + "#]], + ) +} + +#[test] +fn skips_in_record_field_pat_name() { + check( + r#" +struct Foo { bar: Bar } +struct Bar(u32); +fn outer(Foo { bar$0 }: Foo) {} +"#, + expect![[r#""#]], + ) +} -- cgit v1.2.3 From b9d85f55b7a0a2159971b42bb5dae71efbfeada4 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 21 Jun 2021 14:59:49 +0200 Subject: Move out completion type position tests --- .../src/completions/qualified_path.rs | 76 --------- .../src/completions/unqualified_path.rs | 97 ----------- crates/ide_completion/src/tests.rs | 14 +- crates/ide_completion/src/tests/items.rs | 32 ---- crates/ide_completion/src/tests/type_pos.rs | 185 +++++++++++++++++++++ 5 files changed, 198 insertions(+), 206 deletions(-) create mode 100644 crates/ide_completion/src/tests/type_pos.rs (limited to 'crates/ide_completion') diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs index f5dbd203b..1b8997ecf 100644 --- a/crates/ide_completion/src/completions/qualified_path.rs +++ b/crates/ide_completion/src/completions/qualified_path.rs @@ -218,36 +218,6 @@ mod tests { expect.assert_eq(&actual); } - #[test] - fn dont_complete_values_in_type_pos() { - check( - r#" -const FOO: () = (); -static BAR: () = (); -struct Baz; -fn foo() { - let _: self::$0; -} -"#, - expect![[r#" - st Baz - "#]], - ); - } - - #[test] - fn dont_complete_enum_variants_in_type_pos() { - check( - r#" -enum Foo { Bar } -fn foo() { - let _: Foo::$0; -} -"#, - expect![[r#""#]], - ); - } - #[test] fn dont_complete_primitive_in_use() { check_builtin(r#"use self::$0;"#, expect![[""]]); @@ -258,32 +228,6 @@ fn foo() { check_builtin(r#"fn foo() { self::$0 }"#, expect![[""]]); } - #[test] - fn completes_primitives() { - check_builtin( - r#"fn main() { let _: $0 = 92; }"#, - expect![[r#" - 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 completes_enum_variant() { check( @@ -749,24 +693,4 @@ fn main() { "#]], ); } - - #[test] - fn completes_types_and_const_in_arg_list() { - check( - r#" -mod foo { - pub const CONST: () = (); - pub type Type = (); -} - -struct Foo(t); - -fn foo(_: Foo) {} -"#, - expect![[r#" - ta Type - ct CONST - "#]], - ); - } } diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs index 819fa3a43..380c1e079 100644 --- a/crates/ide_completion/src/completions/unqualified_path.rs +++ b/crates/ide_completion/src/completions/unqualified_path.rs @@ -112,28 +112,6 @@ mod tests { expect.assert_eq(&actual) } - #[test] - fn dont_complete_values_in_type_pos() { - check( - r#" -const FOO: () = (); -static BAR: () = (); -enum Foo { - Bar -} -struct Baz; -fn foo() { - let local = (); - let _: $0; -} -"#, - expect![[r#" - en Foo - st Baz - "#]], - ); - } - #[test] fn completes_bindings_from_let() { check( @@ -238,29 +216,6 @@ fn main() { ); } - #[test] - fn completes_generic_params_in_struct() { - check( - r#"struct S { x: $0}"#, - expect![[r#" - sp Self - tp T - st S<…> - "#]], - ); - } - - #[test] - fn completes_self_in_enum() { - check( - r#"enum X { Y($0) }"#, - expect![[r#" - sp Self - en X - "#]], - ); - } - #[test] fn completes_module_items() { check( @@ -314,19 +269,6 @@ mod m { ); } - #[test] - fn completes_return_type() { - check( - r#" -struct Foo; -fn x() -> $0 -"#, - expect![[r#" - st Foo - "#]], - ); - } - #[test] fn dont_show_both_completions_for_shadowing() { check( @@ -508,19 +450,6 @@ fn foo() { $0 } ); } - #[test] - fn completes_macros_as_type() { - check( - r#" -macro_rules! foo { () => {} } -fn main() { let x: $0 } -"#, - expect![[r#" - ma foo!(…) macro_rules! foo - "#]], - ); - } - #[test] fn completes_macros_as_stmt() { check( @@ -666,30 +595,4 @@ fn f() {} expect![[""]], ) } - - #[test] - fn completes_types_and_const_in_arg_list() { - check( - r#" -enum Bar { - Baz -} -trait Foo { - type Bar; -} - -const CONST: () = (); - -fn foo, const CONST_PARAM: usize>(_: T) {} -"#, - expect![[r#" - ta Bar = type Bar; - tp T - cp CONST_PARAM - tt Foo - en Bar - ct CONST - "#]], - ); - } } diff --git a/crates/ide_completion/src/tests.rs b/crates/ide_completion/src/tests.rs index 7af8c903b..97298ff27 100644 --- a/crates/ide_completion/src/tests.rs +++ b/crates/ide_completion/src/tests.rs @@ -8,6 +8,9 @@ mod item_list; mod use_tree; mod items; mod pattern; +mod type_pos; + +use std::mem; use hir::{PrefixKind, Semantics}; use ide_db::{ @@ -46,7 +49,16 @@ pub(crate) fn completion_list(code: &str) -> String { } fn completion_list_with_config(config: CompletionConfig, code: &str) -> String { - render_completion_list(get_all_items(config, code)) + // filter out all but one builtintype completion for smaller test outputs + let items = get_all_items(config, code); + let mut bt_seen = false; + let items = items + .into_iter() + .filter(|it| { + it.completion_kind != CompletionKind::BuiltinType || !mem::replace(&mut bt_seen, true) + }) + .collect(); + render_completion_list(items) } /// Creates analysis from a multi-file fixture, returns positions marked with $0. diff --git a/crates/ide_completion/src/tests/items.rs b/crates/ide_completion/src/tests/items.rs index 8dfb8221b..b98baffd6 100644 --- a/crates/ide_completion/src/tests/items.rs +++ b/crates/ide_completion/src/tests/items.rs @@ -35,22 +35,6 @@ impl Tra$0 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 "##]], ) } @@ -69,22 +53,6 @@ impl Trait for Str$0 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 "##]], ) } diff --git a/crates/ide_completion/src/tests/type_pos.rs b/crates/ide_completion/src/tests/type_pos.rs new file mode 100644 index 000000000..2bfecdd08 --- /dev/null +++ b/crates/ide_completion/src/tests/type_pos.rs @@ -0,0 +1,185 @@ +//! Completions tests for type position. +use expect_test::{expect, Expect}; + +use crate::tests::completion_list; + +fn check_with(ra_fixture: &str, expect: Expect) { + let base = r#" +enum Enum { TupleV(u32), RecordV { field: u32 }, UnitV } +use self::Enum::TupleV; +mod module {} + +trait Trait {} +static STATIC: Unit = Unit; +const CONST: Unit = Unit; +struct Record { field: u32 } +struct Tuple(u32); +struct Unit +macro_rules! makro {} +"#; + let actual = completion_list(&format!("{}\n{}", base, ra_fixture)); + expect.assert_eq(&actual) +} + +#[test] +fn record_field_ty() { + // FIXME: pub shouldnt show up here + check_with( + r#" +struct Foo<'lt, T, const C: usize> { + f: $0 +} +"#, + expect![[r#" + kw pub(crate) + kw pub + sp Self + tp T + tt Trait + en Enum + st Record + st Tuple + md module + st Foo<…> + st Unit + ma makro!(…) macro_rules! makro + bt u32 + "#]], + ) +} + +#[test] +fn tuple_struct_field() { + // FIXME: pub should show up here + check_with( + r#" +struct Foo<'lt, T, const C: usize>(f$0); +"#, + expect![[r#" + sp Self + tp T + tt Trait + en Enum + st Record + st Tuple + md module + st Foo<…> + st Unit + ma makro!(…) macro_rules! makro + bt u32 + "#]], + ) +} + +#[test] +fn fn_return_type() { + // FIXME: return shouldnt show up here + check_with( + r#" +fn x<'lt, T, const C: usize>() -> $0 +"#, + expect![[r#" + kw return + tp T + tt Trait + en Enum + st Record + st Tuple + md module + st Unit + ma makro!(…) macro_rules! makro + bt u32 + "#]], + ); +} + +#[test] +fn body_type_pos() { + // FIXME: return shouldnt show up here + check_with( + r#" +fn foo<'lt, T, const C: usize>() { + let local = (); + let _: $0; +} +"#, + expect![[r#" + kw return + tp T + tt Trait + en Enum + st Record + st Tuple + md module + st Unit + ma makro!(…) macro_rules! makro + bt u32 + "#]], + ); + check_with( + r#" +fn foo<'lt, T, const C: usize>() { + let local = (); + let _: self::$0; +} +"#, + expect![[r#" + tt Trait + en Enum + st Record + st Tuple + md module + st Unit + "#]], + ); +} + +#[test] +fn completes_types_and_const_in_arg_list() { + // FIXME: return shouldnt show up here + // FIXME: we should complete the lifetime here for now + check_with( + r#" +trait Trait2 { + type Foo; +} + +fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {} +"#, + expect![[r#" + kw return + ta Foo = type Foo; + tp T + cp CONST_PARAM + tt Trait + en Enum + st Record + st Tuple + tt Trait2 + md module + st Unit + ct CONST + ma makro!(…) macro_rules! makro + bt u32 + "#]], + ); + check_with( + r#" +trait Trait2 { + type Foo; +} + +fn foo<'lt, T: Trait2, const CONST_PARAM: usize>(_: T) {} + "#, + expect![[r#" + tt Trait + en Enum + st Record + st Tuple + tt Trait2 + md module + st Unit + ct CONST + "#]], + ); +} -- cgit v1.2.3 From 0729913525a55cad3ffe9876c1eb05f7b880d22d Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 21 Jun 2021 15:14:28 +0200 Subject: Various keyword completion fixes --- crates/ide_completion/src/completions/keyword.rs | 6 +++++- crates/ide_completion/src/context.rs | 7 +++++-- crates/ide_completion/src/patterns.rs | 9 ++++++++- crates/ide_completion/src/tests/type_pos.rs | 16 ++++------------ 4 files changed, 22 insertions(+), 16 deletions(-) (limited to 'crates/ide_completion') diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index e40ec6280..407f796ef 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs @@ -92,7 +92,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte } if !ctx.has_visibility_prev_sibling() - && (expects_item || ctx.expects_non_trait_assoc_item() || ctx.expect_record_field()) + && (expects_item || ctx.expects_non_trait_assoc_item() || ctx.expect_field()) { add_keyword("pub(crate)", "pub(crate) "); add_keyword("pub", "pub "); @@ -122,6 +122,10 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte add_keyword("union", "union $1 {\n $0\n}"); } + if ctx.expects_type() { + return; + } + if ctx.expects_expression() { if !has_block_expr_parent { add_keyword("unsafe", "unsafe {\n $0\n}"); diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index e49e434fa..4814bd64d 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs @@ -286,8 +286,11 @@ impl<'a> CompletionContext<'a> { ) } - pub(crate) fn expect_record_field(&self) -> bool { - matches!(self.completion_location, Some(ImmediateLocation::RecordField)) + pub(crate) fn expect_field(&self) -> bool { + matches!( + self.completion_location, + Some(ImmediateLocation::RecordField | ImmediateLocation::TupleField) + ) } pub(crate) fn in_use_tree(&self) -> bool { diff --git a/crates/ide_completion/src/patterns.rs b/crates/ide_completion/src/patterns.rs index 271409c38..757c9a3da 100644 --- a/crates/ide_completion/src/patterns.rs +++ b/crates/ide_completion/src/patterns.rs @@ -31,6 +31,7 @@ pub(crate) enum ImmediateLocation { Impl, Trait, RecordField, + TupleField, RefExpr, IdentPat, BlockExpr, @@ -187,7 +188,13 @@ pub(crate) fn determine_location( ast::SourceFile(_it) => ImmediateLocation::ItemList, ast::ItemList(_it) => ImmediateLocation::ItemList, ast::RefExpr(_it) => ImmediateLocation::RefExpr, - ast::RecordField(_it) => ImmediateLocation::RecordField, + ast::RecordField(it) => if it.ty().map_or(false, |it| it.syntax().text_range().contains(offset)) { + return None; + } else { + ImmediateLocation::RecordField + }, + ast::TupleField(_it) => ImmediateLocation::TupleField, + ast::TupleFieldList(_it) => ImmediateLocation::TupleField, ast::AssocItemList(it) => match it.syntax().parent().map(|it| it.kind()) { Some(IMPL) => ImmediateLocation::Impl, Some(TRAIT) => ImmediateLocation::Trait, diff --git a/crates/ide_completion/src/tests/type_pos.rs b/crates/ide_completion/src/tests/type_pos.rs index 2bfecdd08..1ab47b27e 100644 --- a/crates/ide_completion/src/tests/type_pos.rs +++ b/crates/ide_completion/src/tests/type_pos.rs @@ -23,7 +23,6 @@ macro_rules! makro {} #[test] fn record_field_ty() { - // FIXME: pub shouldnt show up here check_with( r#" struct Foo<'lt, T, const C: usize> { @@ -31,8 +30,6 @@ struct Foo<'lt, T, const C: usize> { } "#, expect![[r#" - kw pub(crate) - kw pub sp Self tp T tt Trait @@ -42,7 +39,7 @@ struct Foo<'lt, T, const C: usize> { md module st Foo<…> st Unit - ma makro!(…) macro_rules! makro + ma makro!(…) macro_rules! makro bt u32 "#]], ) @@ -50,12 +47,13 @@ struct Foo<'lt, T, const C: usize> { #[test] fn tuple_struct_field() { - // FIXME: pub should show up here check_with( r#" struct Foo<'lt, T, const C: usize>(f$0); "#, expect![[r#" + kw pub(crate) + kw pub sp Self tp T tt Trait @@ -65,7 +63,7 @@ struct Foo<'lt, T, const C: usize>(f$0); md module st Foo<…> st Unit - ma makro!(…) macro_rules! makro + ma makro!(…) macro_rules! makro bt u32 "#]], ) @@ -73,13 +71,11 @@ struct Foo<'lt, T, const C: usize>(f$0); #[test] fn fn_return_type() { - // FIXME: return shouldnt show up here check_with( r#" fn x<'lt, T, const C: usize>() -> $0 "#, expect![[r#" - kw return tp T tt Trait en Enum @@ -95,7 +91,6 @@ fn x<'lt, T, const C: usize>() -> $0 #[test] fn body_type_pos() { - // FIXME: return shouldnt show up here check_with( r#" fn foo<'lt, T, const C: usize>() { @@ -104,7 +99,6 @@ fn foo<'lt, T, const C: usize>() { } "#, expect![[r#" - kw return tp T tt Trait en Enum @@ -136,7 +130,6 @@ fn foo<'lt, T, const C: usize>() { #[test] fn completes_types_and_const_in_arg_list() { - // FIXME: return shouldnt show up here // FIXME: we should complete the lifetime here for now check_with( r#" @@ -147,7 +140,6 @@ trait Trait2 { fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {} "#, expect![[r#" - kw return ta Foo = type Foo; tp T cp CONST_PARAM -- cgit v1.2.3