Skip to content

Commit 5d5bbec

Browse files
committed
Auto merge of #12187 - Veykril:completion-rev, r=Veykril
internal: More completion context refactoring
2 parents bfb241a + a0fc649 commit 5d5bbec

26 files changed

+350
-247
lines changed

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

+7-4
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, PathCompletionCtx, PathKind, PathQualifierCtx},
21+
context::{CompletionContext, IdentContext, PathCompletionCtx, PathKind, PathQualifierCtx},
2222
item::CompletionItem,
2323
Completions,
2424
};
@@ -35,7 +35,10 @@ pub(crate) fn complete_known_attribute_input(
3535
acc: &mut Completions,
3636
ctx: &CompletionContext,
3737
) -> Option<()> {
38-
let attribute = ctx.fake_attribute_under_caret.as_ref()?;
38+
let attribute = match &ctx.ident_ctx {
39+
IdentContext::UnexpandedAttrTT { fake_attribute_under_caret: Some(it) } => it,
40+
_ => return None,
41+
};
3942
let name_ref = match attribute.path() {
4043
Some(p) => Some(p.as_single_name_ref()?),
4144
None => None,
@@ -69,8 +72,8 @@ pub(crate) fn complete_known_attribute_input(
6972
}
7073

7174
pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) {
72-
let (is_absolute_path, qualifier, is_inner, annotated_item_kind) = match ctx.path_context {
73-
Some(PathCompletionCtx {
75+
let (is_absolute_path, qualifier, is_inner, annotated_item_kind) = match ctx.path_context() {
76+
Some(&PathCompletionCtx {
7477
kind: PathKind::Attr { kind, annotated_item_kind },
7578
is_absolute_path,
7679
ref qualifier,

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ use crate::{
1111
};
1212

1313
pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
14-
let (qualifier, is_absolute_path) = match ctx.path_context {
15-
Some(PathCompletionCtx {
16-
kind: PathKind::Derive, ref qualifier, is_absolute_path, ..
14+
let (qualifier, is_absolute_path) = match ctx.path_context() {
15+
Some(&PathCompletionCtx {
16+
kind: PathKind::Derive,
17+
ref qualifier,
18+
is_absolute_path,
19+
..
1720
}) => (qualifier, is_absolute_path),
1821
_ => return,
1922
};

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

+12-6
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,21 @@
33
use ide_db::FxHashSet;
44

55
use crate::{
6-
context::{CompletionContext, PathCompletionCtx, PathKind},
7-
patterns::ImmediateLocation,
6+
context::{CompletionContext, DotAccess, NameRefContext, PathCompletionCtx, PathKind},
87
Completions,
98
};
109

1110
/// Complete dot accesses, i.e. fields or methods.
1211
pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
13-
let dot_receiver = match ctx.dot_receiver() {
14-
Some(expr) => expr,
12+
let (dot_access, dot_receiver) = match ctx.nameref_ctx() {
13+
Some(NameRefContext {
14+
dot_access:
15+
Some(
16+
access @ (DotAccess::Method { receiver: Some(receiver), .. }
17+
| DotAccess::Field { receiver: Some(receiver), .. }),
18+
),
19+
..
20+
}) => (access, receiver),
1521
_ => return complete_undotted_self(acc, ctx),
1622
};
1723

@@ -20,7 +26,7 @@ pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
2026
_ => return,
2127
};
2228

23-
if matches!(ctx.completion_location, Some(ImmediateLocation::MethodCall { .. })) {
29+
if let DotAccess::Method { .. } = dot_access {
2430
cov_mark::hit!(test_no_struct_field_completion_for_method_call);
2531
} else {
2632
complete_fields(
@@ -38,7 +44,7 @@ fn complete_undotted_self(acc: &mut Completions, ctx: &CompletionContext) {
3844
if !ctx.config.enable_self_on_the_fly {
3945
return;
4046
}
41-
match ctx.path_context {
47+
match ctx.path_context() {
4248
Some(PathCompletionCtx {
4349
is_absolute_path: false,
4450
qualifier: None,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
1414
return;
1515
}
1616

17-
let (&is_absolute_path, qualifier) = match &ctx.path_context {
17+
let (&is_absolute_path, qualifier) = match ctx.path_context() {
1818
Some(PathCompletionCtx {
1919
kind: PathKind::Expr { .. },
2020
is_absolute_path,

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

+11-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use syntax::{
55
};
66

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

1113
// Most of these are feature gated, we should filter/add feature gate completions once we have them.
@@ -41,10 +43,14 @@ const SUPPORTED_CALLING_CONVENTIONS: &[&str] = &[
4143
];
4244

4345
pub(crate) fn complete_extern_abi(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
44-
if ctx.token.parent().and_then(ast::Abi::cast).is_none() {
45-
return None;
46-
}
47-
let abi_str = ast::String::cast(ctx.token.clone())?;
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+
};
4854
let source_range = abi_str.text_range_between_quotes()?;
4955
for &abi in SUPPORTED_CALLING_CONVENTIONS {
5056
CompletionItem::new(CompletionItemKind::Keyword, source_range, abi).add_to(acc);

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

+2-3
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
119119
return None;
120120
}
121121
// FIXME: This should be encoded in a different way
122-
if ctx.pattern_ctx.is_none() && ctx.path_context.is_none() && !ctx.has_dot_receiver() {
122+
if ctx.pattern_ctx.is_none() && ctx.path_context().is_none() && !ctx.has_dot_receiver() {
123123
// completion inside `ast::Name` of a item declaration
124124
return None;
125125
}
@@ -217,10 +217,9 @@ pub(crate) fn position_for_import(
217217
) -> Option<SyntaxNode> {
218218
Some(
219219
match import_candidate {
220-
Some(ImportCandidate::Path(_)) => ctx.name_syntax.as_ref()?.syntax(),
221220
Some(ImportCandidate::TraitAssocItem(_)) => ctx.path_qual()?.syntax(),
222221
Some(ImportCandidate::TraitMethod(_)) => ctx.dot_receiver()?.syntax(),
223-
None => return ctx.original_token.parent(),
222+
Some(ImportCandidate::Path(_)) | None => return ctx.original_token.parent(),
224223
}
225224
.clone(),
226225
)

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

+11-6
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@
22
33
use ide_db::syntax_helpers::format_string::is_format_string;
44
use itertools::Itertools;
5-
use syntax::{ast, AstToken, TextRange, TextSize};
5+
use syntax::{AstToken, TextRange, TextSize};
66

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

912
/// Complete identifiers in format strings.
1013
pub(crate) fn format_string(acc: &mut Completions, ctx: &CompletionContext) {
11-
let string = match ast::String::cast(ctx.token.clone())
12-
.zip(ast::String::cast(ctx.original_token.clone()))
13-
{
14-
Some((expanded, original)) if is_format_string(&expanded) => original,
14+
let string = match &ctx.ident_ctx {
15+
IdentContext::String { expanded: Some(expanded), original }
16+
if is_format_string(&expanded) =>
17+
{
18+
original
19+
}
1520
_ => return,
1621
};
1722
let cursor = ctx.position.offset;

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
1212
return;
1313
}
1414

15-
let (&is_absolute_path, qualifier) = match &ctx.path_context {
15+
let (&is_absolute_path, qualifier) = match ctx.path_context() {
1616
Some(PathCompletionCtx {
1717
kind: PathKind::Item { .. },
1818
is_absolute_path,

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

+3-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! - `self`, `super` and `crate`, as these are considered part of path completions.
33
//! - `await`, as this is a postfix completion we handle this in the postfix completions.
44
5-
use syntax::{SyntaxKind, T};
5+
use syntax::T;
66

77
use crate::{
88
context::{PathCompletionCtx, PathKind},
@@ -11,18 +11,10 @@ use crate::{
1111
};
1212

1313
pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
14-
if ctx.token.kind() == SyntaxKind::COMMENT {
15-
cov_mark::hit!(no_keyword_completion_in_comments);
16-
return;
17-
}
1814
if matches!(ctx.completion_location, Some(ImmediateLocation::RecordExpr(_))) {
1915
cov_mark::hit!(no_keyword_completion_in_record_lit);
2016
return;
2117
}
22-
if ctx.fake_attribute_under_caret.is_some() {
23-
cov_mark::hit!(no_keyword_completion_in_attr_of_expr);
24-
return;
25-
}
2618
if ctx.is_non_trivial_path() {
2719
cov_mark::hit!(no_keyword_completion_in_non_trivial_path);
2820
return;
@@ -124,8 +116,8 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
124116
add_keyword("mut", "mut ");
125117
}
126118

127-
let (can_be_stmt, in_loop_body) = match ctx.path_context {
128-
Some(PathCompletionCtx {
119+
let (can_be_stmt, in_loop_body) = match ctx.path_context() {
120+
Some(&PathCompletionCtx {
129121
is_absolute_path: false,
130122
kind: PathKind::Expr { in_block_expr, in_loop_body, .. },
131123
..

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

+9-6
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,20 @@ use syntax::{ast, TokenText};
1212

1313
use crate::{
1414
completions::Completions,
15-
context::{CompletionContext, LifetimeContext},
15+
context::{CompletionContext, LifetimeContext, LifetimeKind},
1616
};
1717

1818
/// Completes lifetimes.
1919
pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext) {
20-
let lp = match &ctx.lifetime_ctx {
21-
Some(LifetimeContext::Lifetime) => None,
22-
Some(LifetimeContext::LifetimeParam { is_decl: false, param }) => Some(param),
20+
let (lp, lifetime) = match ctx.lifetime_ctx() {
21+
Some(LifetimeContext { kind: LifetimeKind::Lifetime, lifetime }) => (None, lifetime),
22+
Some(LifetimeContext {
23+
kind: LifetimeKind::LifetimeParam { is_decl: false, param },
24+
lifetime,
25+
}) => (Some(param), lifetime),
2326
_ => return,
2427
};
25-
let param_lifetime = match (ctx.lifetime(), lp.and_then(|lp| lp.lifetime())) {
28+
let param_lifetime = match (lifetime, lp.and_then(|lp| lp.lifetime())) {
2629
(Some(lt), Some(lp)) if lp == lt.clone() => return,
2730
(Some(_), Some(lp)) => Some(lp),
2831
_ => None,
@@ -46,7 +49,7 @@ pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext)
4649

4750
/// Completes labels.
4851
pub(crate) fn complete_label(acc: &mut Completions, ctx: &CompletionContext) {
49-
if !matches!(ctx.lifetime_ctx, Some(LifetimeContext::LabelRef)) {
52+
if !matches!(ctx.lifetime_ctx(), Some(LifetimeContext { kind: LifetimeKind::LabelRef, .. })) {
5053
return;
5154
}
5255
ctx.process_all_names_raw(&mut |name, res| {

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

+9-7
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,23 @@
33
use std::iter;
44

55
use hir::{Module, ModuleSource};
6-
use ide_db::FxHashSet;
76
use ide_db::{
87
base_db::{SourceDatabaseExt, VfsPath},
9-
RootDatabase, SymbolKind,
8+
FxHashSet, RootDatabase, SymbolKind,
109
};
1110
use syntax::{ast, AstNode, SyntaxKind};
1211

13-
use crate::{context::NameContext, CompletionItem};
14-
15-
use crate::{context::CompletionContext, Completions};
12+
use crate::{
13+
context::{CompletionContext, NameContext, NameKind},
14+
CompletionItem, Completions,
15+
};
1616

1717
/// Complete mod declaration, i.e. `mod $0;`
1818
pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
19-
let mod_under_caret = match &ctx.name_ctx {
20-
Some(NameContext::Module(mod_under_caret)) if mod_under_caret.item_list().is_none() => {
19+
let mod_under_caret = match ctx.name_ctx() {
20+
Some(NameContext { kind: NameKind::Module(mod_under_caret), .. })
21+
if mod_under_caret.item_list().is_none() =>
22+
{
2123
mod_under_caret
2224
}
2325
_ => return None,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
1717
};
1818
let refutable = patctx.refutability == PatternRefutability::Refutable;
1919

20-
if let Some(path_ctx) = &ctx.path_context {
20+
if let Some(path_ctx) = ctx.path_context() {
2121
pattern_path_completion(acc, ctx, path_ctx);
2222
return;
2323
}

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

+10-7
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ use text_edit::TextEdit;
1313

1414
use crate::{
1515
completions::postfix::format_like::add_format_like_completions,
16-
context::CompletionContext,
16+
context::{CompletionContext, DotAccess, NameRefContext},
1717
item::{Builder, CompletionRelevancePostfixMatch},
18-
patterns::ImmediateLocation,
1918
CompletionItem, CompletionItemKind, CompletionRelevance, Completions, SnippetScope,
2019
};
2120

@@ -24,11 +23,15 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
2423
return;
2524
}
2625

27-
let (dot_receiver, receiver_is_ambiguous_float_literal) = match &ctx.completion_location {
28-
Some(ImmediateLocation::MethodCall { receiver: Some(it), .. }) => (it, false),
29-
Some(ImmediateLocation::FieldAccess {
30-
receiver: Some(it),
31-
receiver_is_ambiguous_float_literal,
26+
let (dot_receiver, receiver_is_ambiguous_float_literal) = match ctx.nameref_ctx() {
27+
Some(NameRefContext {
28+
dot_access: Some(DotAccess::Method { receiver: Some(it), .. }),
29+
..
30+
}) => (it, false),
31+
Some(NameRefContext {
32+
dot_access:
33+
Some(DotAccess::Field { receiver: Some(it), receiver_is_ambiguous_float_literal }),
34+
..
3235
}) => (it, *receiver_is_ambiguous_float_literal),
3336
_ => return,
3437
};

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str)
1717
}
1818

1919
pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) {
20-
let can_be_stmt = match ctx.path_context {
20+
let &can_be_stmt = match ctx.path_context() {
2121
Some(PathCompletionCtx {
2222
is_absolute_path: false,
2323
qualifier: None,
@@ -43,7 +43,7 @@ pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionConte
4343
}
4444

4545
pub(crate) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionContext) {
46-
let path_kind = match ctx.path_context {
46+
let path_kind = match ctx.path_context() {
4747
Some(PathCompletionCtx {
4848
is_absolute_path: false,
4949
qualifier: None,

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext)
1717
return;
1818
}
1919

20-
let (&is_absolute_path, qualifier) = match &ctx.path_context {
20+
let (&is_absolute_path, qualifier) = match ctx.path_context() {
2121
Some(PathCompletionCtx { kind: PathKind::Type, is_absolute_path, qualifier, .. }) => {
2222
(is_absolute_path, qualifier)
2323
}

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

+9-6
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@ use ide_db::FxHashSet;
55
use syntax::{ast, AstNode};
66

77
use crate::{
8-
context::{CompletionContext, PathCompletionCtx, PathKind, PathQualifierCtx},
8+
context::{CompletionContext, NameRefContext, PathCompletionCtx, PathKind, PathQualifierCtx},
99
item::Builder,
1010
CompletionRelevance, Completions,
1111
};
1212

1313
pub(crate) fn complete_use_tree(acc: &mut Completions, ctx: &CompletionContext) {
14-
let (&is_absolute_path, qualifier) = match &ctx.path_context {
15-
Some(PathCompletionCtx { kind: PathKind::Use, is_absolute_path, qualifier, .. }) => {
16-
(is_absolute_path, qualifier)
17-
}
14+
let (&is_absolute_path, qualifier, name_ref) = match ctx.nameref_ctx() {
15+
Some(NameRefContext {
16+
path_ctx:
17+
Some(PathCompletionCtx { kind: PathKind::Use, is_absolute_path, qualifier, .. }),
18+
nameref,
19+
..
20+
}) => (is_absolute_path, qualifier, nameref),
1821
_ => return,
1922
};
2023

@@ -55,7 +58,7 @@ pub(crate) fn complete_use_tree(acc: &mut Completions, ctx: &CompletionContext)
5558
let module_scope = module.scope(ctx.db, Some(ctx.module));
5659
let unknown_is_current = |name: &hir::Name| {
5760
matches!(
58-
ctx.name_ref(),
61+
name_ref,
5962
Some(name_ref) if name_ref.syntax().text() == name.to_smol_str().as_str()
6063
)
6164
};

0 commit comments

Comments
 (0)