Skip to content

Commit d10e2a0

Browse files
bors[bot]popzxc
andauthored
Merge #6351
6351: Organized completions r=popzxc a=popzxc This PR continues the work on refactoring of the `completions` crate. In this episode: - Actual completions methods are encapsulated into `completions` module, so they aren't mixed with the rest of the code. - Name duplication was removed (`complete_attribute` => `completions::attribute`, `completion_context` => `context`). - `Completions` structure was moved from `item` module to the `completions`. - `presentation` module was removed, as it was basically a module with `impl` for `Completions`. - Code approaches were a bit unified here and there. Co-authored-by: Igor Aleksanov <[email protected]>
2 parents d01e412 + 357bf0c commit d10e2a0

22 files changed

+165
-185
lines changed

crates/completion/src/presentation.rs renamed to crates/completion/src/completions.rs

Lines changed: 72 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,77 @@
1-
//! This modules takes care of rendering various definitions as completion items.
2-
//! It also handles scoring (sorting) completions.
1+
//! This module defines an accumulator for completions which are going to be presented to user.
2+
3+
pub(crate) mod attribute;
4+
pub(crate) mod dot;
5+
pub(crate) mod record;
6+
pub(crate) mod pattern;
7+
pub(crate) mod fn_param;
8+
pub(crate) mod keyword;
9+
pub(crate) mod snippet;
10+
pub(crate) mod qualified_path;
11+
pub(crate) mod unqualified_path;
12+
pub(crate) mod postfix;
13+
pub(crate) mod macro_in_item_position;
14+
pub(crate) mod trait_impl;
15+
pub(crate) mod mod_;
316

417
use hir::{HasAttrs, HasSource, HirDisplay, ModPath, Mutability, ScopeDef, StructKind, Type};
518
use itertools::Itertools;
619
use syntax::{ast::NameOwner, display::*};
720
use test_utils::mark;
821

922
use crate::{
10-
// display::{const_label, function_declaration, macro_label, type_label},
11-
CompletionScore,
12-
RootDatabase,
13-
{
14-
completion_item::Builder, CompletionContext, CompletionItem, CompletionItemKind,
15-
CompletionKind, Completions,
16-
},
23+
item::Builder, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind,
24+
CompletionScore, RootDatabase,
1725
};
1826

27+
/// Represents an in-progress set of completions being built.
28+
#[derive(Debug, Default)]
29+
pub struct Completions {
30+
buf: Vec<CompletionItem>,
31+
}
32+
33+
impl Into<Vec<CompletionItem>> for Completions {
34+
fn into(self) -> Vec<CompletionItem> {
35+
self.buf
36+
}
37+
}
38+
39+
impl Builder {
40+
/// Convenience method, which allows to add a freshly created completion into accumulator
41+
/// without binding it to the variable.
42+
pub(crate) fn add_to(self, acc: &mut Completions) {
43+
acc.add(self.build())
44+
}
45+
}
46+
1947
impl Completions {
48+
pub(crate) fn add(&mut self, item: CompletionItem) {
49+
self.buf.push(item.into())
50+
}
51+
52+
pub(crate) fn add_all<I>(&mut self, items: I)
53+
where
54+
I: IntoIterator,
55+
I::Item: Into<CompletionItem>,
56+
{
57+
items.into_iter().for_each(|item| self.add(item.into()))
58+
}
59+
2060
pub(crate) fn add_field(&mut self, ctx: &CompletionContext, field: hir::Field, ty: &Type) {
2161
let is_deprecated = is_deprecated(field, ctx.db);
2262
let name = field.name(ctx.db);
23-
let mut completion_item =
63+
let mut item =
2464
CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string())
2565
.kind(CompletionItemKind::Field)
2666
.detail(ty.display(ctx.db).to_string())
2767
.set_documentation(field.docs(ctx.db))
2868
.set_deprecated(is_deprecated);
2969

3070
if let Some(score) = compute_score(ctx, &ty, &name.to_string()) {
31-
completion_item = completion_item.set_score(score);
71+
item = item.set_score(score);
3272
}
3373

34-
completion_item.add_to(self);
74+
item.add_to(self);
3575
}
3676

3777
pub(crate) fn add_tuple_field(&mut self, ctx: &CompletionContext, field: usize, ty: &Type) {
@@ -57,15 +97,17 @@ impl Completions {
5797
let kind = match resolution {
5898
ScopeDef::ModuleDef(Module(..)) => CompletionItemKind::Module,
5999
ScopeDef::ModuleDef(Function(func)) => {
60-
return self.add_function(ctx, *func, Some(local_name));
100+
self.add_function(ctx, *func, Some(local_name));
101+
return;
61102
}
62103
ScopeDef::ModuleDef(Adt(hir::Adt::Struct(_))) => CompletionItemKind::Struct,
63104
// FIXME: add CompletionItemKind::Union
64105
ScopeDef::ModuleDef(Adt(hir::Adt::Union(_))) => CompletionItemKind::Struct,
65106
ScopeDef::ModuleDef(Adt(hir::Adt::Enum(_))) => CompletionItemKind::Enum,
66107

67108
ScopeDef::ModuleDef(EnumVariant(var)) => {
68-
return self.add_enum_variant(ctx, *var, Some(local_name));
109+
self.add_enum_variant(ctx, *var, Some(local_name));
110+
return;
69111
}
70112
ScopeDef::ModuleDef(Const(..)) => CompletionItemKind::Const,
71113
ScopeDef::ModuleDef(Static(..)) => CompletionItemKind::Static,
@@ -77,13 +119,14 @@ impl Completions {
77119
// (does this need its own kind?)
78120
ScopeDef::AdtSelfType(..) | ScopeDef::ImplSelfType(..) => CompletionItemKind::TypeParam,
79121
ScopeDef::MacroDef(mac) => {
80-
return self.add_macro(ctx, Some(local_name), *mac);
122+
self.add_macro(ctx, Some(local_name), *mac);
123+
return;
81124
}
82125
ScopeDef::Unknown => {
83-
return self.add(
84-
CompletionItem::new(CompletionKind::Reference, ctx.source_range(), local_name)
85-
.kind(CompletionItemKind::UnresolvedReference),
86-
);
126+
CompletionItem::new(CompletionKind::Reference, ctx.source_range(), local_name)
127+
.kind(CompletionItemKind::UnresolvedReference)
128+
.add_to(self);
129+
return;
87130
}
88131
};
89132

@@ -98,12 +141,11 @@ impl Completions {
98141
_ => None,
99142
};
100143

101-
let mut completion_item =
102-
CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone());
144+
let mut item = CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone());
103145
if let ScopeDef::Local(local) = resolution {
104146
let ty = local.ty(ctx.db);
105147
if !ty.is_unknown() {
106-
completion_item = completion_item.detail(ty.display(ctx.db).to_string());
148+
item = item.detail(ty.display(ctx.db).to_string());
107149
}
108150
};
109151

@@ -114,7 +156,7 @@ impl Completions {
114156
if let Some(score) =
115157
compute_score_from_active(&active_type, &active_name, &ty, &local_name)
116158
{
117-
completion_item = completion_item.set_score(score);
159+
item = item.set_score(score);
118160
}
119161
ref_match = refed_type_matches(&active_type, &active_name, &ty, &local_name);
120162
}
@@ -130,15 +172,15 @@ impl Completions {
130172
};
131173
if has_non_default_type_params {
132174
mark::hit!(inserts_angle_brackets_for_generics);
133-
completion_item = completion_item
175+
item = item
134176
.lookup_by(local_name.clone())
135177
.label(format!("{}<…>", local_name))
136178
.insert_snippet(cap, format!("{}<$0>", local_name));
137179
}
138180
}
139181
}
140182

141-
completion_item.kind(kind).set_documentation(docs).set_ref_match(ref_match).add_to(self)
183+
item.kind(kind).set_documentation(docs).set_ref_match(ref_match).add_to(self)
142184
}
143185

144186
pub(crate) fn add_macro(
@@ -190,7 +232,7 @@ impl Completions {
190232
}
191233
};
192234

193-
self.add(builder);
235+
self.add(builder.build());
194236
}
195237

196238
pub(crate) fn add_function(
@@ -242,7 +284,7 @@ impl Completions {
242284

243285
builder = builder.add_call_parens(ctx, name, Params::Named(params));
244286

245-
self.add(builder)
287+
self.add(builder.build())
246288
}
247289

248290
pub(crate) fn add_const(&mut self, ctx: &CompletionContext, constant: hir::Const) {
@@ -506,7 +548,7 @@ mod tests {
506548
use test_utils::mark;
507549

508550
use crate::{
509-
test_utils::{check_edit, check_edit_with_config, do_completion, get_all_completion_items},
551+
test_utils::{check_edit, check_edit_with_config, do_completion, get_all_items},
510552
CompletionConfig, CompletionKind, CompletionScore,
511553
};
512554

@@ -524,7 +566,7 @@ mod tests {
524566
}
525567
}
526568

527-
let mut completions = get_all_completion_items(CompletionConfig::default(), ra_fixture);
569+
let mut completions = get_all_items(CompletionConfig::default(), ra_fixture);
528570
completions.sort_by_key(|it| (Reverse(it.score()), it.label().to_string()));
529571
let actual = completions
530572
.into_iter()
@@ -661,7 +703,7 @@ fn main() { let _: m::Spam = S<|> }
661703
}
662704

663705
#[test]
664-
fn sets_deprecated_flag_in_completion_items() {
706+
fn sets_deprecated_flag_in_items() {
665707
check(
666708
r#"
667709
#[deprecated]

crates/completion/src/complete_attribute.rs renamed to crates/completion/src/completions/attribute.rs

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ use rustc_hash::FxHashSet;
77
use syntax::{ast, AstNode, SyntaxKind};
88

99
use crate::{
10-
completion_context::CompletionContext,
11-
completion_item::{CompletionItem, CompletionItemKind, CompletionKind, Completions},
10+
context::CompletionContext,
1211
generated_lint_completions::{CLIPPY_LINTS, FEATURES},
12+
item::{CompletionItem, CompletionItemKind, CompletionKind},
13+
Completions,
1314
};
1415

15-
pub(super) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
16+
pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
1617
if ctx.mod_declaration_under_caret.is_some() {
1718
return None;
1819
}
@@ -60,7 +61,7 @@ fn complete_attribute_start(acc: &mut Completions, ctx: &CompletionContext, attr
6061
}
6162

6263
if attribute.kind() == ast::AttrKind::Inner || !attr_completion.prefer_inner {
63-
acc.add(item);
64+
acc.add(item.build());
6465
}
6566
}
6667
}
@@ -152,21 +153,15 @@ fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, derive_input:
152153
label.push_str(", ");
153154
label.push_str(dependency);
154155
}
155-
acc.add(
156-
CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label)
157-
.kind(CompletionItemKind::Attribute),
158-
);
156+
CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label)
157+
.kind(CompletionItemKind::Attribute)
158+
.add_to(acc)
159159
}
160160

161161
for custom_derive_name in get_derive_names_in_scope(ctx).difference(&existing_derives) {
162-
acc.add(
163-
CompletionItem::new(
164-
CompletionKind::Attribute,
165-
ctx.source_range(),
166-
custom_derive_name,
167-
)
168-
.kind(CompletionItemKind::Attribute),
169-
);
162+
CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), custom_derive_name)
163+
.kind(CompletionItemKind::Attribute)
164+
.add_to(acc)
170165
}
171166
}
172167
}
@@ -182,15 +177,14 @@ fn complete_lint(
182177
.into_iter()
183178
.filter(|completion| !existing_lints.contains(completion.label))
184179
{
185-
acc.add(
186-
CompletionItem::new(
187-
CompletionKind::Attribute,
188-
ctx.source_range(),
189-
lint_completion.label,
190-
)
191-
.kind(CompletionItemKind::Attribute)
192-
.detail(lint_completion.description),
193-
);
180+
CompletionItem::new(
181+
CompletionKind::Attribute,
182+
ctx.source_range(),
183+
lint_completion.label,
184+
)
185+
.kind(CompletionItemKind::Attribute)
186+
.detail(lint_completion.description)
187+
.add_to(acc)
194188
}
195189
}
196190
}
@@ -262,9 +256,9 @@ const DEFAULT_DERIVE_COMPLETIONS: &[DeriveCompletion] = &[
262256
DeriveCompletion { label: "Ord", dependencies: &["PartialOrd", "Eq", "PartialEq"] },
263257
];
264258

265-
pub(super) struct LintCompletion {
266-
pub(super) label: &'static str,
267-
pub(super) description: &'static str,
259+
pub(crate) struct LintCompletion {
260+
pub(crate) label: &'static str,
261+
pub(crate) description: &'static str,
268262
}
269263

270264
#[rustfmt::skip]

crates/completion/src/complete_dot.rs renamed to crates/completion/src/completions/dot.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ use hir::{HasVisibility, Type};
44
use rustc_hash::FxHashSet;
55
use test_utils::mark;
66

7-
use crate::{completion_context::CompletionContext, completion_item::Completions};
7+
use crate::{context::CompletionContext, Completions};
88

99
/// Complete dot accesses, i.e. fields or methods.
10-
pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
10+
pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
1111
let dot_receiver = match &ctx.dot_receiver {
1212
Some(expr) => expr,
1313
_ => return,
@@ -141,7 +141,7 @@ mod inner {
141141
private_field: u32,
142142
pub pub_field: u32,
143143
pub(crate) crate_field: u32,
144-
pub(super) super_field: u32,
144+
pub(crate) super_field: u32,
145145
}
146146
}
147147
fn foo(a: inner::A) { a.<|> }
@@ -159,13 +159,13 @@ struct A {}
159159
mod m {
160160
impl super::A {
161161
fn private_method(&self) {}
162-
pub(super) fn the_method(&self) {}
162+
pub(crate) fn the_method(&self) {}
163163
}
164164
}
165165
fn foo(a: A) { a.<|> }
166166
"#,
167167
expect![[r#"
168-
me the_method() pub(super) fn the_method(&self)
168+
me the_method() pub(crate) fn the_method(&self)
169169
"#]],
170170
);
171171
}

crates/completion/src/complete_fn_param.rs renamed to crates/completion/src/completions/fn_param.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::{CompletionContext, CompletionItem, CompletionKind, Completions};
1212
/// functions in a file have a `spam: &mut Spam` parameter, a completion with
1313
/// `spam: &mut Spam` insert text/label and `spam` lookup string will be
1414
/// suggested.
15-
pub(super) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) {
15+
pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) {
1616
if !ctx.is_param {
1717
return;
1818
}

crates/completion/src/complete_keyword.rs renamed to crates/completion/src/completions/keyword.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use test_utils::mark;
55

66
use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions};
77

8-
pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
8+
pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
99
// complete keyword "crate" in use stmt
1010
let source_range = ctx.source_range();
1111

@@ -39,7 +39,7 @@ pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionC
3939
}
4040
}
4141

42-
pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
42+
pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
4343
if ctx.token.kind() == SyntaxKind::COMMENT {
4444
mark::hit!(no_keyword_completion_in_comments);
4545
return;

crates/completion/src/complete_macro_in_item_position.rs renamed to crates/completion/src/completions/macro_in_item_position.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::{CompletionContext, Completions};
44

5-
pub(super) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) {
5+
pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) {
66
// Show only macros in top level.
77
if ctx.is_new_item {
88
ctx.scope.process_all_names(&mut |name, res| {

0 commit comments

Comments
 (0)