diff options
Diffstat (limited to 'crates/ide_completion/src/context.rs')
-rw-r--r-- | crates/ide_completion/src/context.rs | 44 |
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 | } |