Skip to content

Commit 00fdb4a

Browse files
committed
Only run completion functions if their corresponding context is active
1 parent d97a8ee commit 00fdb4a

29 files changed

+561
-396
lines changed

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

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use syntax::{
1818

1919
use crate::{
2020
completions::module_or_attr,
21-
context::{CompletionContext, IdentContext, PathCompletionCtx, PathKind, Qualified},
21+
context::{CompletionContext, PathCompletionCtx, PathKind, Qualified},
2222
item::CompletionItem,
2323
Completions,
2424
};
@@ -34,11 +34,9 @@ pub(crate) use self::derive::complete_derive;
3434
pub(crate) fn complete_known_attribute_input(
3535
acc: &mut Completions,
3636
ctx: &CompletionContext,
37+
fake_attribute_under_caret: &ast::Attr,
3738
) -> Option<()> {
38-
let attribute = match &ctx.ident_ctx {
39-
IdentContext::UnexpandedAttrTT { fake_attribute_under_caret: Some(it) } => it,
40-
_ => return None,
41-
};
39+
let attribute = fake_attribute_under_caret;
4240
let name_ref = match attribute.path() {
4341
Some(p) => Some(p.as_single_name_ref()?),
4442
None => None,
@@ -71,13 +69,17 @@ pub(crate) fn complete_known_attribute_input(
7169
Some(())
7270
}
7371

74-
pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) {
75-
let (qualified, is_inner, annotated_item_kind) = match ctx.path_context() {
76-
Some(&PathCompletionCtx {
72+
pub(crate) fn complete_attribute(
73+
acc: &mut Completions,
74+
ctx: &CompletionContext,
75+
path_ctx: &PathCompletionCtx,
76+
) {
77+
let (qualified, is_inner, annotated_item_kind) = match path_ctx {
78+
&PathCompletionCtx {
7779
kind: PathKind::Attr { kind, annotated_item_kind },
7880
ref qualified,
7981
..
80-
}) => (qualified, kind == AttrKind::Inner, annotated_item_kind),
82+
} => (qualified, kind == AttrKind::Inner, annotated_item_kind),
8183
_ => return,
8284
};
8385

crates/ide-completion/src/completions/attribute/derive.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@ use crate::{
1010
Completions,
1111
};
1212

13-
pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
14-
let (qualified, existing_derives) = match ctx.path_context() {
15-
Some(PathCompletionCtx {
16-
kind: PathKind::Derive { existing_derives }, qualified, ..
17-
}) => (qualified, existing_derives),
13+
pub(crate) fn complete_derive(
14+
acc: &mut Completions,
15+
ctx: &CompletionContext,
16+
path_ctx: &PathCompletionCtx,
17+
) {
18+
let (qualified, existing_derives) = match path_ctx {
19+
PathCompletionCtx { kind: PathKind::Derive { existing_derives }, qualified, .. } => {
20+
(qualified, existing_derives)
21+
}
1822
_ => return,
1923
};
2024

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

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,16 @@ use ide_db::FxHashSet;
44

55
use crate::{
66
context::{
7-
CompletionContext, DotAccess, DotAccessKind, NameRefContext, NameRefKind,
8-
PathCompletionCtx, PathKind, Qualified,
7+
CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind, Qualified,
98
},
109
CompletionItem, CompletionItemKind, Completions,
1110
};
1211

1312
/// Complete dot accesses, i.e. fields or methods.
14-
pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
15-
let (dot_access, receiver_ty) = match ctx.nameref_ctx() {
16-
Some(NameRefContext {
17-
kind:
18-
Some(NameRefKind::DotAccess(access @ DotAccess { receiver_ty: Some(receiver_ty), .. })),
19-
..
20-
}) => (access, &receiver_ty.original),
21-
_ => return complete_undotted_self(acc, ctx),
13+
pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext, dot_access: &DotAccess) {
14+
let receiver_ty = match dot_access {
15+
DotAccess { receiver_ty: Some(receiver_ty), .. } => &receiver_ty.original,
16+
_ => return,
2217
};
2318

2419
// Suggest .await syntax for types that implement Future trait
@@ -43,18 +38,17 @@ pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
4338
complete_methods(ctx, &receiver_ty, |func| acc.add_method(ctx, func, None, None));
4439
}
4540

46-
fn complete_undotted_self(acc: &mut Completions, ctx: &CompletionContext) {
41+
pub(crate) fn complete_undotted_self(
42+
acc: &mut Completions,
43+
ctx: &CompletionContext,
44+
path_ctx: &PathCompletionCtx,
45+
) {
4746
if !ctx.config.enable_self_on_the_fly {
4847
return;
4948
}
50-
match ctx.path_context() {
51-
Some(
52-
path_ctx @ PathCompletionCtx {
53-
qualified: Qualified::No,
54-
kind: PathKind::Expr { .. },
55-
..
56-
},
57-
) if path_ctx.is_trivial_path() && ctx.qualifier_ctx.none() => {}
49+
match path_ctx {
50+
PathCompletionCtx { qualified: Qualified::No, kind: PathKind::Expr { .. }, .. }
51+
if path_ctx.is_trivial_path() && ctx.qualifier_ctx.none() => {}
5852
_ => return,
5953
}
6054

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ use crate::{
88
CompletionContext, Completions,
99
};
1010

11-
pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext) {
11+
pub(crate) fn complete_expr_path(
12+
acc: &mut Completions,
13+
ctx: &CompletionContext,
14+
name_ref_ctx: &NameRefContext,
15+
) {
1216
let _p = profile::span("complete_expr_path");
1317

1418
let (
@@ -19,8 +23,8 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
1923
after_if_expr,
2024
wants_mut_token,
2125
in_condition,
22-
) = match ctx.nameref_ctx() {
23-
Some(&NameRefContext {
26+
) = match name_ref_ctx {
27+
&NameRefContext {
2428
kind:
2529
Some(NameRefKind::Path(PathCompletionCtx {
2630
kind:
@@ -36,7 +40,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
3640
..
3741
})),
3842
..
39-
}) if ctx.qualifier_ctx.none() => (
43+
} if ctx.qualifier_ctx.none() => (
4044
qualified,
4145
in_block_expr,
4246
in_loop_body,

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

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ use syntax::{
55
};
66

77
use crate::{
8-
completions::Completions,
9-
context::{CompletionContext, IdentContext},
10-
CompletionItem, CompletionItemKind,
8+
completions::Completions, context::CompletionContext, CompletionItem, CompletionItemKind,
119
};
1210

1311
// Most of these are feature gated, we should filter/add feature gate completions once we have them.
@@ -42,15 +40,15 @@ const SUPPORTED_CALLING_CONVENTIONS: &[&str] = &[
4240
"unadjusted",
4341
];
4442

45-
pub(crate) fn complete_extern_abi(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
46-
let abi_str = match &ctx.ident_ctx {
47-
IdentContext::String { expanded: Some(expanded), .. }
48-
if expanded.syntax().parent().map_or(false, |it| ast::Abi::can_cast(it.kind())) =>
49-
{
50-
expanded
51-
}
52-
_ => return None,
53-
};
43+
pub(crate) fn complete_extern_abi(
44+
acc: &mut Completions,
45+
_ctx: &CompletionContext,
46+
expanded: &ast::String,
47+
) -> Option<()> {
48+
if !expanded.syntax().parent().map_or(false, |it| ast::Abi::can_cast(it.kind())) {
49+
return None;
50+
}
51+
let abi_str = expanded;
5452
let source_range = abi_str.text_range_between_quotes()?;
5553
for &abi in SUPPORTED_CALLING_CONVENTIONS {
5654
CompletionItem::new(CompletionItemKind::Keyword, source_range, abi).add_to(acc);

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

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
33
use crate::{
44
context::{
5-
IdentContext, NameContext, NameKind, NameRefContext, NameRefKind, PathCompletionCtx,
6-
PathKind, Qualified, TypeLocation,
5+
NameContext, NameKind, NameRefContext, NameRefKind, PathCompletionCtx, PathKind, Qualified,
6+
TypeLocation,
77
},
88
CompletionContext, Completions,
99
};
1010

11-
pub(crate) fn complete_field_list(acc: &mut Completions, ctx: &CompletionContext) {
12-
match &ctx.ident_ctx {
13-
IdentContext::Name(NameContext { kind: NameKind::RecordField, .. })
14-
| IdentContext::NameRef(NameRefContext {
11+
pub(crate) fn complete_field_list_tuple_variant(
12+
acc: &mut Completions,
13+
ctx: &CompletionContext,
14+
name_ref_ctx: &NameRefContext,
15+
) {
16+
match name_ref_ctx {
17+
NameRefContext {
1518
kind:
1619
Some(NameRefKind::Path(PathCompletionCtx {
1720
has_macro_bang: false,
@@ -22,14 +25,29 @@ pub(crate) fn complete_field_list(acc: &mut Completions, ctx: &CompletionContext
2225
..
2326
})),
2427
..
25-
}) => {
28+
} => {
2629
if ctx.qualifier_ctx.vis_node.is_none() {
2730
let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
2831
add_keyword("pub(crate)", "pub(crate)");
2932
add_keyword("pub(super)", "pub(super)");
3033
add_keyword("pub", "pub");
3134
}
3235
}
33-
_ => return,
36+
_ => (),
37+
}
38+
}
39+
40+
pub(crate) fn complete_field_list_record_variant(
41+
acc: &mut Completions,
42+
ctx: &CompletionContext,
43+
name_ctx: &NameContext,
44+
) {
45+
if let NameContext { kind: NameKind::RecordField, .. } = name_ctx {
46+
if ctx.qualifier_ctx.vis_node.is_none() {
47+
let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
48+
add_keyword("pub(crate)", "pub(crate)");
49+
add_keyword("pub(super)", "pub(super)");
50+
add_keyword("pub", "pub");
51+
}
3452
}
3553
}

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ use crate::{
1919
/// `spam: &mut Spam` insert text/label will be suggested.
2020
///
2121
/// Also complete parameters for closure or local functions from the surrounding defined locals.
22-
pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
23-
let (param_list, _, param_kind) = match &ctx.pattern_ctx {
24-
Some(PatternContext { param_ctx: Some(kind), .. }) => kind,
22+
pub(crate) fn complete_fn_param(
23+
acc: &mut Completions,
24+
ctx: &CompletionContext,
25+
pattern_ctx: &PatternContext,
26+
) -> Option<()> {
27+
let (param_list, _, param_kind) = match pattern_ctx {
28+
PatternContext { param_ctx: Some(kind), .. } => kind,
2529
_ => return None,
2630
};
2731

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

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,25 @@
22
33
use ide_db::syntax_helpers::format_string::is_format_string;
44
use itertools::Itertools;
5-
use syntax::{AstToken, TextRange, TextSize};
5+
use syntax::{ast, AstToken, TextRange, TextSize};
66

7-
use crate::{
8-
context::{CompletionContext, IdentContext},
9-
CompletionItem, CompletionItemKind, Completions,
10-
};
7+
use crate::{context::CompletionContext, CompletionItem, CompletionItemKind, Completions};
118

129
/// Complete identifiers in format strings.
13-
pub(crate) fn format_string(acc: &mut Completions, ctx: &CompletionContext) {
14-
let string = match &ctx.ident_ctx {
15-
IdentContext::String { expanded: Some(expanded), original }
16-
if is_format_string(&expanded) =>
17-
{
18-
original
19-
}
20-
_ => return,
21-
};
10+
pub(crate) fn format_string(
11+
acc: &mut Completions,
12+
ctx: &CompletionContext,
13+
original: &ast::String,
14+
expanded: &ast::String,
15+
) {
16+
if !is_format_string(&expanded) {
17+
return;
18+
}
2219
let cursor = ctx.position.offset;
2320
let lit_start = ctx.original_token.text_range().start();
2421
let cursor_in_lit = cursor - lit_start;
2522

26-
let prefix = &string.text()[..cursor_in_lit.into()];
23+
let prefix = &original.text()[..cursor_in_lit.into()];
2724
let braces = prefix.char_indices().rev().skip_while(|&(_, c)| c.is_alphanumeric()).next_tuple();
2825
let brace_offset = match braces {
2926
// escaped brace

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

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,50 @@
22
33
use crate::{
44
completions::module_or_fn_macro,
5-
context::{ItemListKind, PathCompletionCtx, PathKind, Qualified},
5+
context::{ItemListKind, NameRefContext, NameRefKind, PathCompletionCtx, PathKind, Qualified},
66
CompletionContext, Completions,
77
};
88

9-
mod trait_impl;
9+
pub(crate) mod trait_impl;
1010

11-
pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext) {
11+
pub(crate) fn complete_item_list(
12+
acc: &mut Completions,
13+
ctx: &CompletionContext,
14+
name_ref_ctx: &NameRefContext,
15+
) {
1216
let _p = profile::span("complete_item_list");
1317

14-
if let Some(_) = ctx.name_ctx() {
15-
trait_impl::complete_trait_impl(acc, ctx);
16-
return;
17-
}
18-
19-
let (qualified, kind, is_trivial_path) = match ctx.path_context() {
20-
Some(ctx @ PathCompletionCtx { kind: PathKind::Item { kind }, qualified, .. }) => {
21-
(qualified, Some(kind), ctx.is_trivial_path())
22-
}
23-
Some(
24-
ctx @ PathCompletionCtx {
25-
kind: PathKind::Expr { in_block_expr: true, .. },
26-
qualified,
27-
..
28-
},
29-
) => (qualified, None, ctx.is_trivial_path()),
18+
let (qualified, item_list_kind, is_trivial_path) = match name_ref_ctx {
19+
NameRefContext {
20+
kind:
21+
Some(NameRefKind::Path(
22+
ctx @ PathCompletionCtx { kind: PathKind::Item { kind }, qualified, .. },
23+
)),
24+
..
25+
} => (qualified, Some(kind), ctx.is_trivial_path()),
26+
NameRefContext {
27+
kind:
28+
Some(NameRefKind::Path(
29+
ctx @ PathCompletionCtx {
30+
kind: PathKind::Expr { in_block_expr: true, .. },
31+
qualified,
32+
..
33+
},
34+
)),
35+
..
36+
} => (qualified, None, ctx.is_trivial_path()),
3037
_ => return,
3138
};
3239

33-
if matches!(kind, Some(ItemListKind::TraitImpl)) {
34-
trait_impl::complete_trait_impl(acc, ctx);
40+
if matches!(item_list_kind, Some(ItemListKind::TraitImpl)) {
41+
trait_impl::complete_trait_impl_name_ref(acc, ctx, name_ref_ctx);
3542
}
3643

3744
if is_trivial_path {
38-
add_keywords(acc, ctx, kind);
45+
add_keywords(acc, ctx, item_list_kind);
3946
}
4047

41-
if kind.is_none() {
48+
if item_list_kind.is_none() {
4249
// this is already handled by expression
4350
return;
4451
}

0 commit comments

Comments
 (0)