Skip to content

Commit 2e733b1

Browse files
committed
Simplify
1 parent d7374ab commit 2e733b1

File tree

5 files changed

+69
-57
lines changed

5 files changed

+69
-57
lines changed

crates/ide_completion/src/completions/fn_param.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@ use syntax::{
77
};
88

99
use crate::{
10-
context::ParamKind, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind,
11-
Completions,
10+
context::{ParamKind, PatternContext},
11+
CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions,
1212
};
1313

1414
/// Complete repeated parameters, both name and type. For example, if all
1515
/// functions in a file have a `spam: &mut Spam` parameter, a completion with
1616
/// `spam: &mut Spam` insert text/label and `spam` lookup string will be
1717
/// suggested.
1818
pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
19-
if ctx.is_param != Some(ParamKind::Function) {
19+
if !matches!(ctx.pattern_ctx, Some(PatternContext { is_param: Some(ParamKind::Function), .. }))
20+
{
2021
return None;
2122
}
2223

crates/ide_completion/src/completions/pattern.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
//! Completes constants and paths in patterns.
22
3-
use crate::{context::PatternRefutability, CompletionContext, Completions};
3+
use crate::{
4+
context::{PatternContext, PatternRefutability},
5+
CompletionContext, Completions,
6+
};
47

58
/// Completes constants and paths in patterns.
69
pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
7-
let refutable = match ctx.is_pat_or_const {
8-
Some(it) => it == PatternRefutability::Refutable,
10+
let refutable = match ctx.pattern_ctx {
11+
Some(PatternContext { refutability, .. }) => refutability == PatternRefutability::Refutable,
912
None => return,
1013
};
1114

crates/ide_completion/src/context.rs

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ pub(crate) struct PathCompletionContext {
5454
pub(super) in_loop_body: bool,
5555
}
5656

57+
#[derive(Debug)]
58+
pub(super) struct PatternContext {
59+
pub(super) refutability: PatternRefutability,
60+
pub(super) is_param: Option<ParamKind>,
61+
}
62+
5763
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
5864
pub(crate) enum CallKind {
5965
Pat,
@@ -95,15 +101,12 @@ pub(crate) struct CompletionContext<'a> {
95101
pub(super) lifetime_allowed: bool,
96102
pub(super) is_label_ref: bool,
97103

98-
// potentially set if we are completing a name
99-
pub(super) is_pat_or_const: Option<PatternRefutability>,
100-
pub(super) is_param: Option<ParamKind>,
101-
102104
pub(super) completion_location: Option<ImmediateLocation>,
103105
pub(super) prev_sibling: Option<ImmediatePrevSibling>,
104106
pub(super) attribute_under_caret: Option<ast::Attr>,
105107
pub(super) previous_token: Option<SyntaxToken>,
106108

109+
pub(super) pattern_ctx: Option<PatternContext>,
107110
pub(super) path_context: Option<PathCompletionContext>,
108111
pub(super) active_parameter: Option<ActiveParameter>,
109112
pub(super) locals: Vec<(String, Local)>,
@@ -163,8 +166,7 @@ impl<'a> CompletionContext<'a> {
163166
lifetime_param_syntax: None,
164167
lifetime_allowed: false,
165168
is_label_ref: false,
166-
is_pat_or_const: None,
167-
is_param: None,
169+
pattern_ctx: None,
168170
completion_location: None,
169171
prev_sibling: None,
170172
attribute_under_caret: None,
@@ -642,50 +644,51 @@ impl<'a> CompletionContext<'a> {
642644
}
643645

644646
fn classify_name(&mut self, name: ast::Name) {
645-
if let Some(bind_pat) = name.syntax().parent().and_then(ast::IdentPat::cast) {
646-
self.is_pat_or_const = Some(PatternRefutability::Refutable);
647-
if !bind_pat.is_simple_ident() {
648-
self.is_pat_or_const = None;
649-
} else {
650-
let irrefutable_pat = bind_pat.syntax().ancestors().find_map(|node| {
651-
match_ast! {
652-
match node {
653-
ast::LetStmt(it) => Some(it.pat()),
654-
ast::Param(it) => Some(it.pat()),
655-
_ => None,
656-
}
657-
}
658-
});
659-
if let Some(Some(pat)) = irrefutable_pat {
660-
// This check is here since we could be inside a pattern in the initializer expression of the let statement.
661-
if pat.syntax().text_range().contains_range(bind_pat.syntax().text_range()) {
662-
self.is_pat_or_const = Some(PatternRefutability::Irrefutable);
663-
}
664-
}
647+
self.fill_impl_def();
665648

666-
let is_name_in_field_pat = bind_pat
649+
if let Some(bind_pat) = name.syntax().parent().and_then(ast::IdentPat::cast) {
650+
let is_name_in_field_pat = bind_pat
651+
.syntax()
652+
.parent()
653+
.and_then(ast::RecordPatField::cast)
654+
.map_or(false, |pat_field| pat_field.name_ref().is_none());
655+
if is_name_in_field_pat {
656+
return;
657+
}
658+
if bind_pat.is_simple_ident() {
659+
let mut is_param = None;
660+
let refutability = bind_pat
667661
.syntax()
668-
.parent()
669-
.and_then(ast::RecordPatField::cast)
670-
.map_or(false, |pat_field| pat_field.name_ref().is_none());
671-
if is_name_in_field_pat {
672-
self.is_pat_or_const = None;
673-
}
662+
.ancestors()
663+
.skip_while(|it| ast::Pat::can_cast(it.kind()))
664+
.next()
665+
.map_or(PatternRefutability::Irrefutable, |node| {
666+
match_ast! {
667+
match node {
668+
ast::LetStmt(__) => PatternRefutability::Irrefutable,
669+
ast::Param(param) => {
670+
let is_closure_param = param
671+
.syntax()
672+
.ancestors()
673+
.nth(2)
674+
.and_then(ast::ClosureExpr::cast)
675+
.is_some();
676+
is_param = Some(if is_closure_param {
677+
ParamKind::Closure
678+
} else {
679+
ParamKind::Function
680+
});
681+
PatternRefutability::Irrefutable
682+
},
683+
ast::MatchArm(__) => PatternRefutability::Refutable,
684+
ast::Condition(__) => PatternRefutability::Refutable,
685+
ast::ForExpr(__) => PatternRefutability::Irrefutable,
686+
_ => PatternRefutability::Irrefutable,
687+
}
688+
}
689+
});
690+
self.pattern_ctx = Some(PatternContext { refutability, is_param });
674691
}
675-
676-
self.fill_impl_def();
677-
}
678-
679-
if let Some(param) = name
680-
.syntax()
681-
.ancestors()
682-
.find_map(ast::Param::cast)
683-
.filter(|it| it.syntax().text_range() == name.syntax().text_range())
684-
{
685-
let is_closure_param =
686-
param.syntax().ancestors().nth(2).and_then(ast::ClosureExpr::cast).is_some();
687-
self.is_param =
688-
Some(if is_closure_param { ParamKind::Closure } else { ParamKind::Function });
689692
}
690693
}
691694

crates/ide_completion/src/render.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ fn render_resolution_(
167167
hir::ScopeDef::ModuleDef(Function(func)) => {
168168
return render_fn(ctx, import_to_add, Some(local_name), *func);
169169
}
170-
hir::ScopeDef::ModuleDef(Variant(_)) if ctx.completion.is_pat_or_const.is_some() => {
170+
hir::ScopeDef::ModuleDef(Variant(_)) if ctx.completion.pattern_ctx.is_some() => {
171171
CompletionItemKind::SymbolKind(SymbolKind::Variant)
172172
}
173173
hir::ScopeDef::ModuleDef(Variant(var)) => {

crates/ide_completion/src/render/pattern.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ use ide_db::helpers::SnippetCap;
55
use itertools::Itertools;
66

77
use crate::{
8-
context::ParamKind, item::CompletionKind, render::RenderContext, CompletionItem,
9-
CompletionItemKind,
8+
context::{ParamKind, PatternContext},
9+
item::CompletionKind,
10+
render::RenderContext,
11+
CompletionItem, CompletionItemKind,
1012
};
1113

1214
pub(crate) fn render_struct_pat(
@@ -86,7 +88,10 @@ fn render_pat(
8688
_ => return None,
8789
};
8890

89-
if ctx.completion.is_param == Some(ParamKind::Function) {
91+
if matches!(
92+
ctx.completion.pattern_ctx,
93+
Some(PatternContext { is_param: Some(ParamKind::Function), .. })
94+
) {
9095
pat.push(':');
9196
pat.push(' ');
9297
pat.push_str(name);

0 commit comments

Comments
 (0)