aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/context.rs')
-rw-r--r--crates/ide_completion/src/context.rs44
1 files changed, 17 insertions, 27 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 20e033d31..6177caa12 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -43,6 +43,7 @@ pub(crate) struct PathCompletionContext {
43 pub(super) can_be_stmt: bool, 43 pub(super) can_be_stmt: bool,
44 /// `true` if we expect an expression at the cursor position. 44 /// `true` if we expect an expression at the cursor position.
45 pub(super) is_expr: bool, 45 pub(super) is_expr: bool,
46 pub(super) in_loop_body: bool,
46} 47}
47 48
48#[derive(Copy, Clone, Debug, PartialEq, Eq)] 49#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -67,14 +68,13 @@ pub(crate) struct CompletionContext<'a> {
67 pub(super) krate: Option<hir::Crate>, 68 pub(super) krate: Option<hir::Crate>,
68 pub(super) expected_name: Option<NameOrNameRef>, 69 pub(super) expected_name: Option<NameOrNameRef>,
69 pub(super) expected_type: Option<Type>, 70 pub(super) expected_type: Option<Type>,
70 pub(super) name_ref_syntax: Option<ast::NameRef>,
71
72 pub(super) use_item_syntax: Option<ast::Use>,
73 71
74 /// The parent function of the cursor position if it exists. 72 /// The parent function of the cursor position if it exists.
75 pub(super) function_def: Option<ast::Fn>, 73 pub(super) function_def: Option<ast::Fn>,
76 /// The parent impl of the cursor position if it exists. 74 /// The parent impl of the cursor position if it exists.
77 pub(super) impl_def: Option<ast::Impl>, 75 pub(super) impl_def: Option<ast::Impl>,
76 pub(super) name_ref_syntax: Option<ast::NameRef>,
77 pub(super) use_item_syntax: Option<ast::Use>,
78 78
79 // potentially set if we are completing a lifetime 79 // potentially set if we are completing a lifetime
80 pub(super) lifetime_syntax: Option<ast::Lifetime>, 80 pub(super) lifetime_syntax: Option<ast::Lifetime>,
@@ -89,14 +89,12 @@ pub(crate) struct CompletionContext<'a> {
89 pub(super) completion_location: Option<ImmediateLocation>, 89 pub(super) completion_location: Option<ImmediateLocation>,
90 pub(super) prev_sibling: Option<ImmediatePrevSibling>, 90 pub(super) prev_sibling: Option<ImmediatePrevSibling>,
91 pub(super) attribute_under_caret: Option<ast::Attr>, 91 pub(super) attribute_under_caret: Option<ast::Attr>,
92 pub(super) previous_token: Option<SyntaxToken>,
92 93
93 pub(super) path_context: Option<PathCompletionContext>, 94 pub(super) path_context: Option<PathCompletionContext>,
94 /// FIXME: `ActiveParameter` is string-based, which is very very wrong
95 pub(super) active_parameter: Option<ActiveParameter>, 95 pub(super) active_parameter: Option<ActiveParameter>,
96 pub(super) locals: Vec<(String, Local)>, 96 pub(super) locals: Vec<(String, Local)>,
97 97
98 pub(super) previous_token: Option<SyntaxToken>,
99 pub(super) in_loop_body: bool,
100 pub(super) incomplete_let: bool, 98 pub(super) incomplete_let: bool,
101 99
102 no_completion_required: bool, 100 no_completion_required: bool,
@@ -143,28 +141,27 @@ impl<'a> CompletionContext<'a> {
143 original_token, 141 original_token,
144 token, 142 token,
145 krate, 143 krate,
146 lifetime_allowed: false,
147 expected_name: None, 144 expected_name: None,
148 expected_type: None, 145 expected_type: None,
146 function_def: None,
147 impl_def: None,
149 name_ref_syntax: None, 148 name_ref_syntax: None,
149 use_item_syntax: None,
150 lifetime_syntax: None, 150 lifetime_syntax: None,
151 lifetime_param_syntax: None, 151 lifetime_param_syntax: None,
152 function_def: None, 152 lifetime_allowed: false,
153 use_item_syntax: None,
154 impl_def: None,
155 active_parameter: ActiveParameter::at(db, position),
156 is_label_ref: false, 153 is_label_ref: false,
157 is_param: false,
158 is_pat_or_const: None, 154 is_pat_or_const: None,
159 path_context: None, 155 is_param: false,
160 previous_token: None,
161 in_loop_body: false,
162 completion_location: None, 156 completion_location: None,
163 prev_sibling: None, 157 prev_sibling: None,
164 no_completion_required: false,
165 incomplete_let: false,
166 attribute_under_caret: None, 158 attribute_under_caret: None,
159 previous_token: None,
160 path_context: None,
161 active_parameter: ActiveParameter::at(db, position),
167 locals, 162 locals,
163 incomplete_let: false,
164 no_completion_required: false,
168 }; 165 };
169 166
170 let mut original_file = original_file.syntax().clone(); 167 let mut original_file = original_file.syntax().clone();
@@ -326,10 +323,6 @@ impl<'a> CompletionContext<'a> {
326 self.path_context.as_ref().and_then(|it| it.path_qual.as_ref()) 323 self.path_context.as_ref().and_then(|it| it.path_qual.as_ref())
327 } 324 }
328 325
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
333 fn fill_impl_def(&mut self) { 326 fn fill_impl_def(&mut self) {
334 self.impl_def = self 327 self.impl_def = self
335 .sema 328 .sema
@@ -455,7 +448,6 @@ impl<'a> CompletionContext<'a> {
455 let for_is_prev2 = for_is_prev2(syntax_element.clone()); 448 let for_is_prev2 = for_is_prev2(syntax_element.clone());
456 (fn_is_prev && !inside_impl_trait_block) || for_is_prev2 449 (fn_is_prev && !inside_impl_trait_block) || for_is_prev2
457 }; 450 };
458 self.in_loop_body = is_in_loop_body(syntax_element.clone());
459 451
460 self.incomplete_let = 452 self.incomplete_let =
461 syntax_element.ancestors().take(6).find_map(ast::LetStmt::cast).map_or(false, |it| { 453 syntax_element.ancestors().take(6).find_map(ast::LetStmt::cast).map_or(false, |it| {
@@ -563,10 +555,6 @@ impl<'a> CompletionContext<'a> {
563 self.name_ref_syntax = 555 self.name_ref_syntax =
564 find_node_at_offset(original_file, name_ref.syntax().text_range().start()); 556 find_node_at_offset(original_file, name_ref.syntax().text_range().start());
565 557
566 if matches!(self.completion_location, Some(ImmediateLocation::ItemList)) {
567 return;
568 }
569
570 self.use_item_syntax = 558 self.use_item_syntax =
571 self.sema.token_ancestors_with_macros(self.token.clone()).find_map(ast::Use::cast); 559 self.sema.token_ancestors_with_macros(self.token.clone()).find_map(ast::Use::cast);
572 560
@@ -590,14 +578,16 @@ impl<'a> CompletionContext<'a> {
590 is_path_type: false, 578 is_path_type: false,
591 can_be_stmt: false, 579 can_be_stmt: false,
592 is_expr: false, 580 is_expr: false,
581 in_loop_body: false,
593 }); 582 });
583 path_ctx.in_loop_body = is_in_loop_body(name_ref.syntax());
594 let path = segment.parent_path(); 584 let path = segment.parent_path();
595 585
596 if let Some(p) = path.syntax().parent() { 586 if let Some(p) = path.syntax().parent() {
597 path_ctx.call_kind = match_ast! { 587 path_ctx.call_kind = match_ast! {
598 match p { 588 match p {
599 ast::PathExpr(it) => it.syntax().parent().and_then(ast::CallExpr::cast).map(|_| CallKind::Expr), 589 ast::PathExpr(it) => it.syntax().parent().and_then(ast::CallExpr::cast).map(|_| CallKind::Expr),
600 ast::MacroCall(_it) => Some(CallKind::Mac), 590 ast::MacroCall(it) => it.excl_token().and(Some(CallKind::Mac)),
601 ast::TupleStructPat(_it) => Some(CallKind::Pat), 591 ast::TupleStructPat(_it) => Some(CallKind::Pat),
602 _ => None 592 _ => None
603 } 593 }