Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 522f665

Browse files
committed
Remove prev-sibling completion machinery
1 parent 6550a24 commit 522f665

File tree

3 files changed

+21
-76
lines changed

3 files changed

+21
-76
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
1515
return;
1616
}
1717

18-
let (is_absolute_path, qualifier, in_block_expr, in_loop_body, is_func_update) =
18+
let (is_absolute_path, qualifier, in_block_expr, in_loop_body, is_func_update, after_if_expr) =
1919
match ctx.nameref_ctx() {
2020
Some(NameRefContext {
2121
path_ctx:
2222
Some(PathCompletionCtx {
23-
kind: PathKind::Expr { in_block_expr, in_loop_body },
23+
kind: PathKind::Expr { in_block_expr, in_loop_body, after_if_expr },
2424
is_absolute_path,
2525
qualifier,
2626
..
@@ -33,6 +33,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
3333
*in_block_expr,
3434
*in_loop_body,
3535
record_expr.as_ref().map_or(false, |&(_, it)| it),
36+
*after_if_expr,
3637
),
3738
_ => return,
3839
};
@@ -202,7 +203,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
202203
add_keyword("let", "let");
203204
}
204205

205-
if ctx.after_if() {
206+
if after_if_expr {
206207
add_keyword("else", "else {\n $0\n}");
207208
add_keyword("else if", "else if $1 {\n $0\n}");
208209
}

crates/ide-completion/src/context.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ use ide_db::{
1515
use syntax::{
1616
algo::{find_node_at_offset, non_trivia_sibling},
1717
ast::{self, AttrKind, HasArgList, HasName, NameOrNameRef},
18-
match_ast, AstNode, AstToken, NodeOrToken,
18+
match_ast, AstNode, AstToken, Direction, NodeOrToken,
1919
SyntaxKind::{self, *},
2020
SyntaxNode, SyntaxToken, TextRange, TextSize, T,
2121
};
2222
use text_edit::Indel;
2323

2424
use crate::{
2525
patterns::{
26-
determine_location, determine_prev_sibling, is_in_loop_body, is_in_token_of_for_loop,
27-
previous_token, ImmediateLocation, ImmediatePrevSibling,
26+
determine_location, is_in_loop_body, is_in_token_of_for_loop, previous_token,
27+
ImmediateLocation,
2828
},
2929
CompletionConfig,
3030
};
@@ -48,6 +48,7 @@ pub(super) enum PathKind {
4848
Expr {
4949
in_block_expr: bool,
5050
in_loop_body: bool,
51+
after_if_expr: bool,
5152
},
5253
Type {
5354
in_tuple_struct: bool,
@@ -264,7 +265,6 @@ pub(crate) struct CompletionContext<'a> {
264265
pub(super) incomplete_let: bool,
265266

266267
pub(super) completion_location: Option<ImmediateLocation>,
267-
pub(super) prev_sibling: Option<ImmediatePrevSibling>,
268268
pub(super) previous_token: Option<SyntaxToken>,
269269

270270
pub(super) ident_ctx: IdentContext,
@@ -345,10 +345,6 @@ impl<'a> CompletionContext<'a> {
345345
matches!(self.completion_location, Some(ImmediateLocation::RefExpr))
346346
}
347347

348-
pub(crate) fn after_if(&self) -> bool {
349-
matches!(self.prev_sibling, Some(ImmediatePrevSibling::IfExpr))
350-
}
351-
352348
// FIXME: This shouldn't exist
353349
pub(crate) fn is_path_disallowed(&self) -> bool {
354350
!self.qualifier_ctx.none()
@@ -527,7 +523,6 @@ impl<'a> CompletionContext<'a> {
527523
impl_def: None,
528524
incomplete_let: false,
529525
completion_location: None,
530-
prev_sibling: None,
531526
previous_token: None,
532527
// dummy value, will be overwritten
533528
ident_ctx: IdentContext::UnexpandedAttrTT { fake_attribute_under_caret: None },
@@ -922,7 +917,6 @@ impl<'a> CompletionContext<'a> {
922917
};
923918
self.completion_location =
924919
determine_location(&self.sema, original_file, offset, &name_like);
925-
self.prev_sibling = determine_prev_sibling(&name_like);
926920
self.impl_def = self
927921
.sema
928922
.token_ancestors_with_macros(self.token.clone())
@@ -1169,6 +1163,13 @@ impl<'a> CompletionContext<'a> {
11691163
find_node_in_file_compensated(original_file, &record_expr).zip(Some(true));
11701164
}
11711165
};
1166+
let after_if_expr = |node: SyntaxNode| {
1167+
let prev_expr = (|| {
1168+
let prev_sibling = non_trivia_sibling(node.into(), Direction::Prev)?.into_node()?;
1169+
ast::ExprStmt::cast(prev_sibling)?.expr()
1170+
})();
1171+
matches!(prev_expr, Some(ast::Expr::IfExpr(_)))
1172+
};
11721173

11731174
// We do not want to generate path completions when we are sandwiched between an item decl signature and its body.
11741175
// ex. trait Foo $0 {}
@@ -1226,7 +1227,9 @@ impl<'a> CompletionContext<'a> {
12261227
path_ctx.has_call_parens = it.syntax().parent().map_or(false, |it| ast::CallExpr::can_cast(it.kind()));
12271228
let in_block_expr = is_in_block(it.syntax());
12281229
let in_loop_body = is_in_loop_body(it.syntax());
1229-
Some(PathKind::Expr { in_block_expr, in_loop_body })
1230+
let after_if_expr = after_if_expr(it.syntax().clone());
1231+
1232+
Some(PathKind::Expr { in_block_expr, in_loop_body, after_if_expr })
12301233
},
12311234
ast::TupleStructPat(it) => {
12321235
path_ctx.has_call_parens = true;
@@ -1274,8 +1277,9 @@ impl<'a> CompletionContext<'a> {
12741277
return Some(parent.and_then(ast::MacroExpr::cast).map(|it| {
12751278
let in_loop_body = is_in_loop_body(it.syntax());
12761279
let in_block_expr = is_in_block(it.syntax());
1280+
let after_if_expr = after_if_expr(it.syntax().clone());
12771281
fill_record_expr(it.syntax());
1278-
PathKind::Expr { in_block_expr, in_loop_body }
1282+
PathKind::Expr { in_block_expr, in_loop_body, after_if_expr }
12791283
}));
12801284
},
12811285
}

crates/ide-completion/src/patterns.rs

Lines changed: 1 addition & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,15 @@
77
use hir::Semantics;
88
use ide_db::RootDatabase;
99
use syntax::{
10-
algo::non_trivia_sibling,
1110
ast::{self, HasLoopBody, HasName},
12-
match_ast, AstNode, Direction, SyntaxElement,
11+
match_ast, AstNode, SyntaxElement,
1312
SyntaxKind::*,
1413
SyntaxNode, SyntaxToken, TextRange, TextSize,
1514
};
1615

1716
#[cfg(test)]
1817
use crate::tests::check_pattern_is_applicable;
1918

20-
/// Immediate previous node to what we are completing.
21-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
22-
pub(crate) enum ImmediatePrevSibling {
23-
IfExpr,
24-
}
25-
2619
#[derive(Clone, Debug, PartialEq, Eq)]
2720
pub(crate) enum TypeAnnotation {
2821
Let(Option<ast::Pat>),
@@ -46,45 +39,6 @@ pub(crate) enum ImmediateLocation {
4639
GenericArgList(ast::GenericArgList),
4740
}
4841

49-
pub(crate) fn determine_prev_sibling(name_like: &ast::NameLike) -> Option<ImmediatePrevSibling> {
50-
let node = match name_like {
51-
ast::NameLike::NameRef(name_ref) => maximize_name_ref(name_ref),
52-
ast::NameLike::Name(n) => n.syntax().clone(),
53-
ast::NameLike::Lifetime(lt) => lt.syntax().clone(),
54-
};
55-
let node = match node.parent().and_then(ast::MacroCall::cast) {
56-
// When a path is being typed after the name of a trait/type of an impl it is being
57-
// parsed as a macro, so when the trait/impl has a block following it an we are between the
58-
// name and block the macro will attach the block to itself so maximizing fails to take
59-
// that into account
60-
// FIXME path expr and statement have a similar problem with attrs
61-
Some(call)
62-
if call.excl_token().is_none()
63-
&& call.token_tree().map_or(false, |t| t.l_curly_token().is_some())
64-
&& call.semicolon_token().is_none() =>
65-
{
66-
call.syntax().clone()
67-
}
68-
_ => node,
69-
};
70-
let prev_sibling = non_trivia_sibling(node.into(), Direction::Prev)?.into_node()?;
71-
let res = match_ast! {
72-
match prev_sibling {
73-
ast::ExprStmt(it) => {
74-
let node = it.expr().filter(|_| it.semicolon_token().is_none())?.syntax().clone();
75-
match_ast! {
76-
match node {
77-
ast::IfExpr(_) => ImmediatePrevSibling::IfExpr,
78-
_ => return None,
79-
}
80-
}
81-
},
82-
_ => return None,
83-
}
84-
};
85-
Some(res)
86-
}
87-
8842
pub(crate) fn determine_location(
8943
sema: &Semantics<RootDatabase>,
9044
original_file: &SyntaxNode,
@@ -316,22 +270,8 @@ mod tests {
316270
);
317271
}
318272

319-
fn check_prev_sibling(code: &str, sibling: impl Into<Option<ImmediatePrevSibling>>) {
320-
check_pattern_is_applicable(code, |e| {
321-
let name = &e.parent().and_then(ast::NameLike::cast).expect("Expected a namelike");
322-
assert_eq!(determine_prev_sibling(name), sibling.into());
323-
true
324-
});
325-
}
326-
327273
#[test]
328274
fn test_ref_expr_loc() {
329275
check_location(r"fn my_fn() { let x = &m$0 foo; }", ImmediateLocation::RefExpr);
330276
}
331-
332-
#[test]
333-
fn test_if_expr_prev_sibling() {
334-
check_prev_sibling(r"fn foo() { if true {} w$0", ImmediatePrevSibling::IfExpr);
335-
check_prev_sibling(r"fn foo() { if true {}; w$0", None);
336-
}
337277
}

0 commit comments

Comments
 (0)