Merge #9356
9356: internal: Move out and regroup more completion tests r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
c69f762f26
@ -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}");
|
||||
@ -372,28 +376,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);
|
||||
|
@ -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#""#]],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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>(t);
|
||||
|
||||
fn foo(_: Foo<foo::$0>) {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
ta Type
|
||||
ct CONST
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -112,78 +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 bind_pat_and_path_ignore_at() {
|
||||
check(
|
||||
r#"
|
||||
enum Enum { A, B }
|
||||
fn quux(x: Option<Enum>) {
|
||||
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<Enum>) {
|
||||
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<Enum>) {
|
||||
match x {
|
||||
None => (),
|
||||
Some(En$0) => (),
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
en Enum
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completes_bindings_from_let() {
|
||||
check(
|
||||
@ -288,29 +216,6 @@ fn main() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completes_generic_params_in_struct() {
|
||||
check(
|
||||
r#"struct S<T> { 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(
|
||||
@ -364,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(
|
||||
@ -558,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(
|
||||
@ -716,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<T: Foo<$0>, const CONST_PARAM: usize>(_: T) {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
ta Bar = type Bar;
|
||||
tp T
|
||||
cp CONST_PARAM
|
||||
tt Foo
|
||||
en Bar
|
||||
ct CONST
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -7,6 +7,10 @@
|
||||
mod item_list;
|
||||
mod use_tree;
|
||||
mod items;
|
||||
mod pattern;
|
||||
mod type_pos;
|
||||
|
||||
use std::mem;
|
||||
|
||||
use hir::{PrefixKind, Semantics};
|
||||
use ide_db::{
|
||||
@ -45,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.
|
||||
|
@ -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
|
||||
"##]],
|
||||
)
|
||||
}
|
||||
|
348
crates/ide_completion/src/tests/pattern.rs
Normal file
348
crates/ide_completion/src/tests/pattern.rs
Normal file
@ -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#""#]],
|
||||
)
|
||||
}
|
177
crates/ide_completion/src/tests/type_pos.rs
Normal file
177
crates/ide_completion/src/tests/type_pos.rs
Normal file
@ -0,0 +1,177 @@
|
||||
//! 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() {
|
||||
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 tuple_struct_field() {
|
||||
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 fn_return_type() {
|
||||
check_with(
|
||||
r#"
|
||||
fn x<'lt, T, const C: usize>() -> $0
|
||||
"#,
|
||||
expect![[r#"
|
||||
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() {
|
||||
check_with(
|
||||
r#"
|
||||
fn foo<'lt, T, const C: usize>() {
|
||||
let local = ();
|
||||
let _: $0;
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
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: 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#"
|
||||
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<self::$0>, const CONST_PARAM: usize>(_: T) {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
tt Trait
|
||||
en Enum
|
||||
st Record
|
||||
st Tuple
|
||||
tt Trait2
|
||||
md module
|
||||
st Unit
|
||||
ct CONST
|
||||
"#]],
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user