Skip to content

Commit 4eabcb2

Browse files
committed
Move more things into PathCompletionContext
1 parent e475bcd commit 4eabcb2

File tree

8 files changed

+62
-46
lines changed

8 files changed

+62
-46
lines changed

crates/ide_completion/src/completions/dot.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn complete_undotted_self(acc: &mut Completions, ctx: &CompletionContext) {
3333
if !ctx.config.enable_self_on_the_fly {
3434
return;
3535
}
36-
if !ctx.is_trivial_path || ctx.is_path_disallowed() {
36+
if !ctx.is_trivial_path() || ctx.is_path_disallowed() {
3737
return;
3838
}
3939
ctx.scope.process_all_names(&mut |name, def| {

crates/ide_completion/src/completions/flyimport.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,13 @@ pub(crate) fn position_for_import<'a>(
161161
) -> Option<&'a SyntaxNode> {
162162
Some(match import_candidate {
163163
Some(ImportCandidate::Path(_)) => ctx.name_ref_syntax.as_ref()?.syntax(),
164-
Some(ImportCandidate::TraitAssocItem(_)) => ctx.path_qual.as_ref()?.syntax(),
164+
Some(ImportCandidate::TraitAssocItem(_)) => ctx.path_qual()?.syntax(),
165165
Some(ImportCandidate::TraitMethod(_)) => ctx.dot_receiver()?.syntax(),
166166
None => ctx
167167
.name_ref_syntax
168168
.as_ref()
169169
.map(|name_ref| name_ref.syntax())
170-
.or_else(|| ctx.path_qual.as_ref().map(|path| path.syntax()))
170+
.or_else(|| ctx.path_qual().map(|path| path.syntax()))
171171
.or_else(|| ctx.dot_receiver().map(|expr| expr.syntax()))?,
172172
})
173173
}
@@ -190,7 +190,7 @@ fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option<ImportAs
190190
};
191191
let assets_for_path = ImportAssets::for_fuzzy_path(
192192
current_module,
193-
ctx.path_qual.clone(),
193+
ctx.path_qual().cloned(),
194194
fuzzy_name,
195195
&ctx.sema,
196196
approximate_node,

crates/ide_completion/src/completions/keyword.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionC
1919
};
2020

2121
if ctx.use_item_syntax.is_some() {
22-
if ctx.path_qual.is_none() {
22+
let qual = ctx.path_qual();
23+
if qual.is_none() {
2324
kw_completion("crate::").add_to(acc);
2425
}
2526
kw_completion("self").add_to(acc);
26-
if iter::successors(ctx.path_qual.clone(), |p| p.qualifier())
27+
if iter::successors(qual.cloned(), |p| p.qualifier())
2728
.all(|p| p.segment().and_then(|s| s.super_token()).is_some())
2829
{
2930
kw_completion("super::").add_to(acc);
@@ -128,7 +129,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
128129
}
129130

130131
if ctx.in_loop_body {
131-
if ctx.can_be_stmt {
132+
if ctx.can_be_stmt() {
132133
add_keyword("continue", "continue;");
133134
add_keyword("break", "break;");
134135
} else {
@@ -137,7 +138,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
137138
}
138139
}
139140

140-
if !ctx.is_trivial_path {
141+
if !ctx.is_trivial_path() {
141142
return;
142143
}
143144
let fn_def = match &ctx.function_def {
@@ -147,7 +148,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
147148

148149
add_keyword(
149150
"return",
150-
match (ctx.can_be_stmt, fn_def.ret_type().is_some()) {
151+
match (ctx.can_be_stmt(), fn_def.ret_type().is_some()) {
151152
(true, true) => "return $0;",
152153
(true, false) => "return;",
153154
(false, true) => "return $0",

crates/ide_completion/src/completions/qualified_path.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
1010
if ctx.is_path_disallowed() || ctx.expects_item() {
1111
return;
1212
}
13-
let path = match &ctx.path_qual {
14-
Some(path) => path.clone(),
13+
let path = match ctx.path_qual() {
14+
Some(path) => path,
1515
None => return,
1616
};
1717

crates/ide_completion/src/completions/snippet.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str)
1414
}
1515

1616
pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) {
17-
if !(ctx.is_trivial_path && ctx.function_def.is_some()) {
17+
if !(ctx.is_trivial_path() && ctx.function_def.is_some()) {
1818
return;
1919
}
2020
let cap = match ctx.config.snippet_cap {
2121
Some(it) => it,
2222
None => return,
2323
};
2424

25-
if ctx.can_be_stmt {
25+
if ctx.can_be_stmt() {
2626
snippet(ctx, cap, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc);
2727
snippet(ctx, cap, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc);
2828
}

crates/ide_completion/src/completions/unqualified_path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use hir::ScopeDef;
55
use crate::{CompletionContext, Completions};
66

77
pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
8-
if !ctx.is_trivial_path {
8+
if !ctx.is_trivial_path() {
99
return;
1010
}
1111
if ctx.is_path_disallowed() || ctx.expects_item() {

crates/ide_completion/src/context.rs

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ pub(crate) enum PatternRefutability {
3333
pub(crate) struct PathCompletionContext {
3434
/// If this is a call with () already there
3535
call_kind: Option<CallKind>,
36+
/// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
37+
pub(super) is_trivial_path: bool,
38+
/// If not a trivial path, the prefix (qualifier).
39+
pub(super) path_qual: Option<ast::Path>,
40+
pub(super) is_path_type: bool,
41+
pub(super) has_type_args: bool,
42+
/// `true` if we are a statement or a last expr in the block.
43+
pub(super) can_be_stmt: bool,
44+
/// `true` if we expect an expression at the cursor position.
45+
pub(super) is_expr: bool,
3646
}
3747

3848
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -83,16 +93,6 @@ pub(crate) struct CompletionContext<'a> {
8393
pub(super) path_context: Option<PathCompletionContext>,
8494
/// FIXME: `ActiveParameter` is string-based, which is very very wrong
8595
pub(super) active_parameter: Option<ActiveParameter>,
86-
/// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
87-
pub(super) is_trivial_path: bool,
88-
/// If not a trivial path, the prefix (qualifier).
89-
pub(super) path_qual: Option<ast::Path>,
90-
/// `true` if we are a statement or a last expr in the block.
91-
pub(super) can_be_stmt: bool,
92-
/// `true` if we expect an expression at the cursor position.
93-
pub(super) is_expr: bool,
94-
pub(super) is_path_type: bool,
95-
pub(super) has_type_args: bool,
9696
pub(super) locals: Vec<(String, Local)>,
9797

9898
pub(super) previous_token: Option<SyntaxToken>,
@@ -156,13 +156,7 @@ impl<'a> CompletionContext<'a> {
156156
is_label_ref: false,
157157
is_param: false,
158158
is_pat_or_const: None,
159-
is_trivial_path: false,
160-
path_qual: None,
161-
can_be_stmt: false,
162-
is_expr: false,
163159
path_context: None,
164-
is_path_type: false,
165-
has_type_args: false,
166160
previous_token: None,
167161
in_loop_body: false,
168162
completion_location: None,
@@ -280,11 +274,6 @@ impl<'a> CompletionContext<'a> {
280274
matches!(self.completion_location, Some(ImmediateLocation::ItemList))
281275
}
282276

283-
// fn expects_value(&self) -> bool {
284-
pub(crate) fn expects_expression(&self) -> bool {
285-
self.is_expr
286-
}
287-
288277
pub(crate) fn has_block_expr_parent(&self) -> bool {
289278
matches!(self.completion_location, Some(ImmediateLocation::BlockExpr))
290279
}
@@ -321,10 +310,26 @@ impl<'a> CompletionContext<'a> {
321310
) || self.attribute_under_caret.is_some()
322311
}
323312

313+
pub(crate) fn expects_expression(&self) -> bool {
314+
self.path_context.as_ref().map_or(false, |it| it.is_expr)
315+
}
316+
324317
pub(crate) fn path_call_kind(&self) -> Option<CallKind> {
325318
self.path_context.as_ref().and_then(|it| it.call_kind)
326319
}
327320

321+
pub(crate) fn is_trivial_path(&self) -> bool {
322+
self.path_context.as_ref().map_or(false, |it| it.is_trivial_path)
323+
}
324+
325+
pub(crate) fn path_qual(&self) -> Option<&ast::Path> {
326+
self.path_context.as_ref().and_then(|it| it.path_qual.as_ref())
327+
}
328+
329+
pub(crate) fn can_be_stmt(&self) -> bool {
330+
self.path_context.as_ref().map_or(false, |it| it.can_be_stmt)
331+
}
332+
328333
fn fill_impl_def(&mut self) {
329334
self.impl_def = self
330335
.sema
@@ -577,7 +582,15 @@ impl<'a> CompletionContext<'a> {
577582
};
578583

579584
if let Some(segment) = ast::PathSegment::cast(parent) {
580-
let mut path_ctx = PathCompletionContext { call_kind: None };
585+
let path_ctx = self.path_context.get_or_insert(PathCompletionContext {
586+
call_kind: None,
587+
is_trivial_path: false,
588+
path_qual: None,
589+
has_type_args: false,
590+
is_path_type: false,
591+
can_be_stmt: false,
592+
is_expr: false,
593+
});
581594
let path = segment.parent_path();
582595

583596
if let Some(p) = path.syntax().parent() {
@@ -590,13 +603,11 @@ impl<'a> CompletionContext<'a> {
590603
}
591604
};
592605
}
593-
self.path_context = Some(path_ctx);
594-
dbg!(&self.path_context);
595-
self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some();
596-
self.has_type_args = segment.generic_arg_list().is_some();
606+
path_ctx.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some();
607+
path_ctx.has_type_args = segment.generic_arg_list().is_some();
597608

598609
if let Some(path) = path_or_use_tree_qualifier(&path) {
599-
self.path_qual = path
610+
path_ctx.path_qual = path
600611
.segment()
601612
.and_then(|it| {
602613
find_node_with_range::<ast::PathSegment>(
@@ -614,11 +625,11 @@ impl<'a> CompletionContext<'a> {
614625
}
615626
}
616627

617-
self.is_trivial_path = true;
628+
path_ctx.is_trivial_path = true;
618629

619630
// Find either enclosing expr statement (thing with `;`) or a
620631
// block. If block, check that we are the last expr.
621-
self.can_be_stmt = name_ref
632+
path_ctx.can_be_stmt = name_ref
622633
.syntax()
623634
.ancestors()
624635
.find_map(|node| {
@@ -634,7 +645,7 @@ impl<'a> CompletionContext<'a> {
634645
None
635646
})
636647
.unwrap_or(false);
637-
self.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some();
648+
path_ctx.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some();
638649
}
639650
}
640651
}

crates/ide_completion/src/render.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,12 @@ impl<'a> Render<'a> {
275275
};
276276

277277
// Add `<>` for generic types
278-
if self.ctx.completion.is_path_type
279-
&& !self.ctx.completion.has_type_args
278+
if self
279+
.ctx
280+
.completion
281+
.path_context
282+
.as_ref()
283+
.map_or(false, |it| it.is_path_type && !it.has_type_args)
280284
&& self.ctx.completion.config.add_call_parenthesis
281285
{
282286
if let Some(cap) = self.ctx.snippet_cap() {

0 commit comments

Comments
 (0)