Make else autocompletion work in more places

This commit is contained in:
Lukas Wirth 2023-02-12 10:49:57 +01:00
parent 33cacde04b
commit d2cf8c234a
3 changed files with 305 additions and 39 deletions

View File

@ -380,7 +380,7 @@ fn expected_type_and_name(
sema,
token.clone(),
).map(|ap| {
let name = dbg!(ap.ident().map(NameOrNameRef::Name));
let name = ap.ident().map(NameOrNameRef::Name);
let ty = strip_refs(ap.ty);
(Some(ty), name)
@ -656,8 +656,15 @@ fn classify_name_ref(
};
let after_if_expr = |node: SyntaxNode| {
let prev_expr = (|| {
let node = match node.parent().and_then(ast::ExprStmt::cast) {
Some(stmt) => stmt.syntax().clone(),
None => node,
};
let prev_sibling = non_trivia_sibling(node.into(), Direction::Prev)?.into_node()?;
ast::ExprStmt::cast(prev_sibling)?.expr()
ast::ExprStmt::cast(prev_sibling.clone())
.and_then(|it| it.expr())
.or_else(|| ast::Expr::cast(prev_sibling))
})();
matches!(prev_expr, Some(ast::Expr::IfExpr(_)))
};

View File

@ -745,3 +745,255 @@ fn return_value_no_block() {
r#"fn f() -> i32 { match () { () => return $0 } }"#,
);
}
#[test]
fn else_completion_after_if() {
check_empty(
r#"
fn foo() { if foo {} $0 }
"#,
expect![[r#"
fn foo() fn()
bt u32
kw const
kw crate::
kw else
kw else if
kw enum
kw extern
kw false
kw fn
kw for
kw if
kw if let
kw impl
kw let
kw loop
kw match
kw mod
kw return
kw self::
kw static
kw struct
kw trait
kw true
kw type
kw union
kw unsafe
kw use
kw while
kw while let
sn macro_rules
sn pd
sn ppd
"#]],
);
check_empty(
r#"
fn foo() { if foo {} el$0 }
"#,
expect![[r#"
fn foo() fn()
bt u32
kw const
kw crate::
kw else
kw else if
kw enum
kw extern
kw false
kw fn
kw for
kw if
kw if let
kw impl
kw let
kw loop
kw match
kw mod
kw return
kw self::
kw static
kw struct
kw trait
kw true
kw type
kw union
kw unsafe
kw use
kw while
kw while let
sn macro_rules
sn pd
sn ppd
"#]],
);
check_empty(
r#"
fn foo() { bar(if foo {} $0) }
"#,
expect![[r#"
fn foo() fn()
bt u32
kw crate::
kw else
kw else if
kw false
kw for
kw if
kw if let
kw loop
kw match
kw return
kw self::
kw true
kw unsafe
kw while
kw while let
"#]],
);
check_empty(
r#"
fn foo() { bar(if foo {} el$0) }
"#,
expect![[r#"
fn foo() fn()
bt u32
kw crate::
kw else
kw else if
kw false
kw for
kw if
kw if let
kw loop
kw match
kw return
kw self::
kw true
kw unsafe
kw while
kw while let
"#]],
);
check_empty(
r#"
fn foo() { if foo {} $0 let x = 92; }
"#,
expect![[r#"
fn foo() fn()
bt u32
kw const
kw crate::
kw else
kw else if
kw enum
kw extern
kw false
kw fn
kw for
kw if
kw if let
kw impl
kw let
kw loop
kw match
kw mod
kw return
kw self::
kw static
kw struct
kw trait
kw true
kw type
kw union
kw unsafe
kw use
kw while
kw while let
sn macro_rules
sn pd
sn ppd
"#]],
);
check_empty(
r#"
fn foo() { if foo {} el$0 let x = 92; }
"#,
expect![[r#"
fn foo() fn()
bt u32
kw const
kw crate::
kw else
kw else if
kw enum
kw extern
kw false
kw fn
kw for
kw if
kw if let
kw impl
kw let
kw loop
kw match
kw mod
kw return
kw self::
kw static
kw struct
kw trait
kw true
kw type
kw union
kw unsafe
kw use
kw while
kw while let
sn macro_rules
sn pd
sn ppd
"#]],
);
check_empty(
r#"
fn foo() { if foo {} el$0 { let x = 92; } }
"#,
expect![[r#"
fn foo() fn()
bt u32
kw const
kw crate::
kw else
kw else if
kw enum
kw extern
kw false
kw fn
kw for
kw if
kw if let
kw impl
kw let
kw loop
kw match
kw mod
kw return
kw self::
kw static
kw struct
kw trait
kw true
kw type
kw union
kw unsafe
kw use
kw while
kw while let
sn macro_rules
sn pd
sn ppd
"#]],
);
}

View File

@ -2,10 +2,17 @@
use expect_test::{expect, Expect};
use crate::tests::{check_edit, completion_list_no_kw, completion_list_with_trigger_character};
use crate::tests::{
check_edit, completion_list, completion_list_no_kw, completion_list_with_trigger_character,
};
fn check_no_kw(ra_fixture: &str, expect: Expect) {
let actual = completion_list_no_kw(ra_fixture);
expect.assert_eq(&actual)
}
fn check(ra_fixture: &str, expect: Expect) {
let actual = completion_list_no_kw(ra_fixture);
let actual = completion_list(ra_fixture);
expect.assert_eq(&actual)
}
@ -59,7 +66,7 @@ fn _alpha() {}
#[test]
fn completes_prelude() {
check(
check_no_kw(
r#"
//- /main.rs edition:2018 crate:main deps:std
fn foo() { let x: $0 }
@ -81,7 +88,7 @@ pub mod prelude {
#[test]
fn completes_prelude_macros() {
check(
check_no_kw(
r#"
//- /main.rs edition:2018 crate:main deps:std
fn f() {$0}
@ -110,7 +117,7 @@ mod macros {
#[test]
fn completes_std_prelude_if_core_is_defined() {
check(
check_no_kw(
r#"
//- /main.rs crate:main deps:core,std
fn foo() { let x: $0 }
@ -140,7 +147,7 @@ pub mod prelude {
#[test]
fn respects_doc_hidden() {
check(
check_no_kw(
r#"
//- /lib.rs crate:lib deps:std
fn f() {
@ -168,7 +175,7 @@ pub mod prelude {
#[test]
fn respects_doc_hidden_in_assoc_item_list() {
check(
check_no_kw(
r#"
//- /lib.rs crate:lib deps:std
struct S;
@ -195,7 +202,7 @@ pub mod prelude {
#[test]
fn associated_item_visibility() {
check(
check_no_kw(
r#"
//- /lib.rs crate:lib new_source_root:library
pub struct S;
@ -222,7 +229,7 @@ fn foo() { let _ = lib::S::$0 }
#[test]
fn completes_union_associated_method() {
check(
check_no_kw(
r#"
union U {};
impl U { fn m() { } }
@ -237,7 +244,7 @@ fn foo() { let _ = U::$0 }
#[test]
fn completes_trait_associated_method_1() {
check(
check_no_kw(
r#"
trait Trait { fn m(); }
@ -251,7 +258,7 @@ fn foo() { let _ = Trait::$0 }
#[test]
fn completes_trait_associated_method_2() {
check(
check_no_kw(
r#"
trait Trait { fn m(); }
@ -268,7 +275,7 @@ fn foo() { let _ = S::$0 }
#[test]
fn completes_trait_associated_method_3() {
check(
check_no_kw(
r#"
trait Trait { fn m(); }
@ -285,7 +292,7 @@ fn foo() { let _ = <S as Trait>::$0 }
#[test]
fn completes_ty_param_assoc_ty() {
check(
check_no_kw(
r#"
trait Super {
type Ty;
@ -318,7 +325,7 @@ fn foo<T: Sub>() { T::$0 }
#[test]
fn completes_self_param_assoc_ty() {
check(
check_no_kw(
r#"
trait Super {
type Ty;
@ -358,7 +365,7 @@ impl<T> Sub for Wrap<T> {
#[test]
fn completes_type_alias() {
check(
check_no_kw(
r#"
struct S;
impl S { fn foo() {} }
@ -376,7 +383,7 @@ fn main() { T::$0; }
#[test]
fn completes_qualified_macros() {
check(
check_no_kw(
r#"
#[macro_export]
macro_rules! foo { () => {} }
@ -392,7 +399,7 @@ fn main() { let _ = crate::$0 }
#[test]
fn does_not_complete_non_fn_macros() {
check(
check_no_kw(
r#"
mod m {
#[rustc_builtin_macro]
@ -403,7 +410,7 @@ fn f() {m::$0}
"#,
expect![[r#""#]],
);
check(
check_no_kw(
r#"
mod m {
#[rustc_builtin_macro]
@ -418,7 +425,7 @@ fn f() {m::$0}
#[test]
fn completes_reexported_items_under_correct_name() {
check(
check_no_kw(
r#"
fn foo() { self::m::$0 }
@ -475,7 +482,7 @@ mod p {
#[test]
fn completes_in_simple_macro_call() {
check(
check_no_kw(
r#"
macro_rules! m { ($e:expr) => { $e } }
fn main() { m!(self::f$0); }
@ -490,7 +497,7 @@ fn foo() {}
#[test]
fn function_mod_share_name() {
check(
check_no_kw(
r#"
fn foo() { self::m::$0 }
@ -508,7 +515,7 @@ mod m {
#[test]
fn completes_hashmap_new() {
check(
check_no_kw(
r#"
struct RandomState;
struct HashMap<K, V, S = RandomState> {}
@ -529,7 +536,7 @@ fn foo() {
#[test]
fn completes_variant_through_self() {
cov_mark::check!(completes_variant_through_self);
check(
check_no_kw(
r#"
enum Foo {
Bar,
@ -552,7 +559,7 @@ impl Foo {
#[test]
fn completes_non_exhaustive_variant_within_the_defining_crate() {
check(
check_no_kw(
r#"
enum Foo {
#[non_exhaustive]
@ -570,7 +577,7 @@ fn foo(self) {
"#]],
);
check(
check_no_kw(
r#"
//- /main.rs crate:main deps:e
fn foo(self) {
@ -593,7 +600,7 @@ enum Foo {
#[test]
fn completes_primitive_assoc_const() {
cov_mark::check!(completes_primitive_assoc_const);
check(
check_no_kw(
r#"
//- /lib.rs crate:lib deps:core
fn f() {
@ -618,7 +625,7 @@ impl u8 {
#[test]
fn completes_variant_through_alias() {
cov_mark::check!(completes_variant_through_alias);
check(
check_no_kw(
r#"
enum Foo {
Bar
@ -636,7 +643,7 @@ fn main() {
#[test]
fn respects_doc_hidden2() {
check(
check_no_kw(
r#"
//- /lib.rs crate:lib deps:dep
fn f() {
@ -665,7 +672,7 @@ pub mod m {}
#[test]
fn type_anchor_empty() {
check(
check_no_kw(
r#"
trait Foo {
fn foo() -> Self;
@ -688,7 +695,7 @@ fn bar() -> Bar {
#[test]
fn type_anchor_type() {
check(
check_no_kw(
r#"
trait Foo {
fn foo() -> Self;
@ -715,7 +722,7 @@ fn bar() -> Bar {
#[test]
fn type_anchor_type_trait() {
check(
check_no_kw(
r#"
trait Foo {
fn foo() -> Self;
@ -741,7 +748,7 @@ fn bar() -> Bar {
#[test]
fn completes_fn_in_pub_trait_generated_by_macro() {
check(
check_no_kw(
r#"
mod other_mod {
macro_rules! make_method {
@ -775,7 +782,7 @@ fn main() {
#[test]
fn completes_fn_in_pub_trait_generated_by_recursive_macro() {
check(
check_no_kw(
r#"
mod other_mod {
macro_rules! make_method {
@ -815,7 +822,7 @@ fn main() {
#[test]
fn completes_const_in_pub_trait_generated_by_macro() {
check(
check_no_kw(
r#"
mod other_mod {
macro_rules! make_const {
@ -847,7 +854,7 @@ fn main() {
#[test]
fn completes_locals_from_macros() {
check(
check_no_kw(
r#"
macro_rules! x {
@ -875,7 +882,7 @@ fn main() {
#[test]
fn regression_12644() {
check(
check_no_kw(
r#"
macro_rules! __rust_force_expr {
($e:expr) => {
@ -974,7 +981,7 @@ fn foo { crate:::$0 }
"#,
expect![""],
);
check(
check_no_kw(
r#"
fn foo { crate::::$0 }
"#,