Skip to content

Commit 30cd10a

Browse files
authored
Merge pull request #20658 from A4-Tacks/more-expr-else-after-if
Fix else completion for more expressions
2 parents 5844df0 + b96babe commit 30cd10a

File tree

4 files changed

+312
-5
lines changed

4 files changed

+312
-5
lines changed

crates/ide-completion/src/completions/pattern.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ pub(crate) fn complete_pattern(
4242
}
4343
}
4444

45+
if pattern_ctx.after_if_expr {
46+
add_keyword("else", "else {\n $0\n}");
47+
add_keyword("else if", "else if $1 {\n $0\n}");
48+
}
49+
4550
if pattern_ctx.record_pat.is_some() {
4651
return;
4752
}

crates/ide-completion/src/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ pub(crate) struct PatternContext {
279279
pub(crate) param_ctx: Option<ParamContext>,
280280
pub(crate) has_type_ascription: bool,
281281
pub(crate) should_suggest_name: bool,
282+
pub(crate) after_if_expr: bool,
282283
pub(crate) parent_pat: Option<ast::Pat>,
283284
pub(crate) ref_token: Option<SyntaxToken>,
284285
pub(crate) mut_token: Option<SyntaxToken>,

crates/ide-completion/src/context/analysis.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -999,10 +999,6 @@ fn classify_name_ref<'db>(
999999
}
10001000
}
10011001
};
1002-
let after_if_expr = |node: SyntaxNode| {
1003-
let prev_expr = prev_expr(node);
1004-
matches!(prev_expr, Some(ast::Expr::IfExpr(_)))
1005-
};
10061002
let after_incomplete_let = |node: SyntaxNode| {
10071003
prev_expr(node).and_then(|it| it.syntax().parent()).and_then(ast::LetStmt::cast)
10081004
};
@@ -1242,7 +1238,7 @@ fn classify_name_ref<'db>(
12421238
let it = expr.syntax();
12431239
let in_block_expr = is_in_block(it);
12441240
let (in_loop_body, innermost_breakable) = is_in_breakable(it).unzip();
1245-
let after_if_expr = after_if_expr(it.clone());
1241+
let after_if_expr = is_after_if_expr(it.clone());
12461242
let ref_expr_parent =
12471243
path.as_single_name_ref().and_then(|_| it.parent()).and_then(ast::RefExpr::cast);
12481244
let after_amp = non_trivia_sibling(it.clone().into(), Direction::Prev)
@@ -1763,6 +1759,7 @@ fn pattern_context_for(
17631759
param_ctx,
17641760
has_type_ascription,
17651761
should_suggest_name,
1762+
after_if_expr: is_after_if_expr(pat.syntax().clone()),
17661763
parent_pat: pat.syntax().parent().and_then(ast::Pat::cast),
17671764
mut_token,
17681765
ref_token,
@@ -1933,6 +1930,18 @@ fn has_in_newline_expr_first(node: &SyntaxNode) -> bool {
19331930
}
19341931
}
19351932

1933+
fn is_after_if_expr(node: SyntaxNode) -> bool {
1934+
let node = match node.parent().and_then(Either::<ast::ExprStmt, ast::MatchArm>::cast) {
1935+
Some(stmt) => stmt.syntax().clone(),
1936+
None => node,
1937+
};
1938+
let prev_sibling =
1939+
non_trivia_sibling(node.into(), Direction::Prev).and_then(NodeOrToken::into_node);
1940+
iter::successors(prev_sibling, |it| it.last_child_or_token()?.into_node())
1941+
.find_map(ast::IfExpr::cast)
1942+
.is_some()
1943+
}
1944+
19361945
fn next_non_trivia_token(e: impl Into<SyntaxElement>) -> Option<SyntaxToken> {
19371946
let mut token = match e.into() {
19381947
SyntaxElement::Node(n) => n.last_token()?,

crates/ide-completion/src/tests/expression.rs

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,6 +1869,298 @@ fn foo() { let x = if foo {} $0 else if true {} else {}; }
18691869
sn ppd
18701870
"#]],
18711871
);
1872+
check(
1873+
r#"
1874+
fn foo() { [if foo {} $0]}
1875+
"#,
1876+
expect![[r#"
1877+
fn foo() fn()
1878+
bt u32 u32
1879+
kw async
1880+
kw const
1881+
kw crate::
1882+
kw else
1883+
kw else if
1884+
kw enum
1885+
kw extern
1886+
kw false
1887+
kw fn
1888+
kw for
1889+
kw if
1890+
kw if let
1891+
kw impl
1892+
kw impl for
1893+
kw let
1894+
kw letm
1895+
kw loop
1896+
kw match
1897+
kw mod
1898+
kw return
1899+
kw self::
1900+
kw static
1901+
kw struct
1902+
kw trait
1903+
kw true
1904+
kw type
1905+
kw union
1906+
kw unsafe
1907+
kw use
1908+
kw while
1909+
kw while let
1910+
sn macro_rules
1911+
sn pd
1912+
sn ppd
1913+
"#]],
1914+
);
1915+
check(
1916+
r#"
1917+
fn foo() { [if foo {} el$0]}
1918+
"#,
1919+
expect![[r#"
1920+
fn foo() fn()
1921+
bt u32 u32
1922+
kw async
1923+
kw const
1924+
kw crate::
1925+
kw else
1926+
kw else if
1927+
kw enum
1928+
kw extern
1929+
kw false
1930+
kw fn
1931+
kw for
1932+
kw if
1933+
kw if let
1934+
kw impl
1935+
kw impl for
1936+
kw let
1937+
kw letm
1938+
kw loop
1939+
kw match
1940+
kw mod
1941+
kw return
1942+
kw self::
1943+
kw static
1944+
kw struct
1945+
kw trait
1946+
kw true
1947+
kw type
1948+
kw union
1949+
kw unsafe
1950+
kw use
1951+
kw while
1952+
kw while let
1953+
sn macro_rules
1954+
sn pd
1955+
sn ppd
1956+
"#]],
1957+
);
1958+
check(
1959+
r#"
1960+
fn foo() { 2 + if foo {} $0 }
1961+
"#,
1962+
expect![[r#"
1963+
fn foo() fn()
1964+
bt u32 u32
1965+
kw async
1966+
kw const
1967+
kw crate::
1968+
kw else
1969+
kw else if
1970+
kw enum
1971+
kw extern
1972+
kw false
1973+
kw fn
1974+
kw for
1975+
kw if
1976+
kw if let
1977+
kw impl
1978+
kw impl for
1979+
kw let
1980+
kw letm
1981+
kw loop
1982+
kw match
1983+
kw mod
1984+
kw return
1985+
kw self::
1986+
kw static
1987+
kw struct
1988+
kw trait
1989+
kw true
1990+
kw type
1991+
kw union
1992+
kw unsafe
1993+
kw use
1994+
kw while
1995+
kw while let
1996+
sn macro_rules
1997+
sn pd
1998+
sn ppd
1999+
"#]],
2000+
);
2001+
check(
2002+
r#"
2003+
fn foo() { -if foo {} $0 }
2004+
"#,
2005+
expect![[r#"
2006+
fn foo() fn()
2007+
bt u32 u32
2008+
kw async
2009+
kw const
2010+
kw crate::
2011+
kw else
2012+
kw else if
2013+
kw enum
2014+
kw extern
2015+
kw false
2016+
kw fn
2017+
kw for
2018+
kw if
2019+
kw if let
2020+
kw impl
2021+
kw impl for
2022+
kw let
2023+
kw letm
2024+
kw loop
2025+
kw match
2026+
kw mod
2027+
kw return
2028+
kw self::
2029+
kw static
2030+
kw struct
2031+
kw trait
2032+
kw true
2033+
kw type
2034+
kw union
2035+
kw unsafe
2036+
kw use
2037+
kw while
2038+
kw while let
2039+
sn macro_rules
2040+
sn pd
2041+
sn ppd
2042+
"#]],
2043+
);
2044+
check(
2045+
r#"
2046+
fn foo() { &mut if foo {} $0 }
2047+
"#,
2048+
expect![[r#"
2049+
fn foo() fn()
2050+
bt u32 u32
2051+
kw async
2052+
kw const
2053+
kw crate::
2054+
kw else
2055+
kw else if
2056+
kw enum
2057+
kw extern
2058+
kw false
2059+
kw fn
2060+
kw for
2061+
kw if
2062+
kw if let
2063+
kw impl
2064+
kw impl for
2065+
kw let
2066+
kw letm
2067+
kw loop
2068+
kw match
2069+
kw mod
2070+
kw return
2071+
kw self::
2072+
kw static
2073+
kw struct
2074+
kw trait
2075+
kw true
2076+
kw type
2077+
kw union
2078+
kw unsafe
2079+
kw use
2080+
kw while
2081+
kw while let
2082+
sn macro_rules
2083+
sn pd
2084+
sn ppd
2085+
"#]],
2086+
);
2087+
check(
2088+
r#"
2089+
fn foo() { return if foo {} $0 }
2090+
"#,
2091+
expect![[r#"
2092+
fn foo() fn()
2093+
bt u32 u32
2094+
kw async
2095+
kw const
2096+
kw crate::
2097+
kw else
2098+
kw else if
2099+
kw enum
2100+
kw extern
2101+
kw false
2102+
kw fn
2103+
kw for
2104+
kw if
2105+
kw if let
2106+
kw impl
2107+
kw impl for
2108+
kw let
2109+
kw letm
2110+
kw loop
2111+
kw match
2112+
kw mod
2113+
kw return
2114+
kw self::
2115+
kw static
2116+
kw struct
2117+
kw trait
2118+
kw true
2119+
kw type
2120+
kw union
2121+
kw unsafe
2122+
kw use
2123+
kw while
2124+
kw while let
2125+
sn macro_rules
2126+
sn pd
2127+
sn ppd
2128+
"#]],
2129+
);
2130+
check(
2131+
r#"
2132+
fn foo() { match () { () => if foo {} $0 } }
2133+
"#,
2134+
expect![[r#"
2135+
kw else
2136+
kw else if
2137+
kw mut
2138+
kw ref
2139+
"#]],
2140+
);
2141+
check(
2142+
r#"
2143+
fn foo() { match () { () => if foo {} $0, } }
2144+
"#,
2145+
expect![[r#"
2146+
kw else
2147+
kw else if
2148+
kw mut
2149+
kw ref
2150+
"#]],
2151+
);
2152+
check(
2153+
r#"
2154+
fn foo() { match () { () => if foo {} $0, _ => (), } }
2155+
"#,
2156+
expect![[r#"
2157+
kw else
2158+
kw else if
2159+
kw mut
2160+
kw ref
2161+
"#]],
2162+
);
2163+
// FIXME: support else completion after ast::RecordExprField
18722164
}
18732165

18742166
#[test]

0 commit comments

Comments
 (0)