diff options
Diffstat (limited to 'crates/ide_completion/src/context.rs')
-rw-r--r-- | crates/ide_completion/src/context.rs | 40 |
1 files changed, 12 insertions, 28 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index faf8469a5..8d6440cb2 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs | |||
@@ -17,8 +17,8 @@ use text_edit::Indel; | |||
17 | 17 | ||
18 | use crate::{ | 18 | use crate::{ |
19 | patterns::{ | 19 | patterns::{ |
20 | determine_location, for_is_prev2, has_prev_sibling, inside_impl_trait_block, | 20 | determine_location, determine_prev_sibling, for_is_prev2, inside_impl_trait_block, |
21 | is_in_loop_body, is_match_arm, previous_token, ImmediateLocation, | 21 | is_in_loop_body, is_match_arm, previous_token, ImmediateLocation, ImmediatePrevSibling, |
22 | }, | 22 | }, |
23 | CompletionConfig, | 23 | CompletionConfig, |
24 | }; | 24 | }; |
@@ -29,12 +29,6 @@ pub(crate) enum PatternRefutability { | |||
29 | Irrefutable, | 29 | Irrefutable, |
30 | } | 30 | } |
31 | 31 | ||
32 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] | ||
33 | pub(crate) enum PrevSibling { | ||
34 | Trait, | ||
35 | Impl, | ||
36 | } | ||
37 | |||
38 | /// `CompletionContext` is created early during completion to figure out, where | 32 | /// `CompletionContext` is created early during completion to figure out, where |
39 | /// exactly is the cursor, syntax-wise. | 33 | /// exactly is the cursor, syntax-wise. |
40 | #[derive(Debug)] | 34 | #[derive(Debug)] |
@@ -76,6 +70,7 @@ pub(crate) struct CompletionContext<'a> { | |||
76 | pub(super) is_param: bool, | 70 | pub(super) is_param: bool, |
77 | 71 | ||
78 | pub(super) completion_location: Option<ImmediateLocation>, | 72 | pub(super) completion_location: Option<ImmediateLocation>, |
73 | pub(super) prev_sibling: Option<ImmediatePrevSibling>, | ||
79 | 74 | ||
80 | /// FIXME: `ActiveParameter` is string-based, which is very very wrong | 75 | /// FIXME: `ActiveParameter` is string-based, which is very very wrong |
81 | pub(super) active_parameter: Option<ActiveParameter>, | 76 | pub(super) active_parameter: Option<ActiveParameter>, |
@@ -83,7 +78,6 @@ pub(crate) struct CompletionContext<'a> { | |||
83 | pub(super) is_trivial_path: bool, | 78 | pub(super) is_trivial_path: bool, |
84 | /// If not a trivial path, the prefix (qualifier). | 79 | /// If not a trivial path, the prefix (qualifier). |
85 | pub(super) path_qual: Option<ast::Path>, | 80 | pub(super) path_qual: Option<ast::Path>, |
86 | pub(super) after_if: bool, | ||
87 | /// `true` if we are a statement or a last expr in the block. | 81 | /// `true` if we are a statement or a last expr in the block. |
88 | pub(super) can_be_stmt: bool, | 82 | pub(super) can_be_stmt: bool, |
89 | /// `true` if we expect an expression at the cursor position. | 83 | /// `true` if we expect an expression at the cursor position. |
@@ -107,7 +101,6 @@ pub(crate) struct CompletionContext<'a> { | |||
107 | 101 | ||
108 | // keyword patterns | 102 | // keyword patterns |
109 | pub(super) previous_token: Option<SyntaxToken>, | 103 | pub(super) previous_token: Option<SyntaxToken>, |
110 | pub(super) prev_sibling: Option<PrevSibling>, | ||
111 | pub(super) in_loop_body: bool, | 104 | pub(super) in_loop_body: bool, |
112 | pub(super) is_match_arm: bool, | 105 | pub(super) is_match_arm: bool, |
113 | pub(super) incomplete_let: bool, | 106 | pub(super) incomplete_let: bool, |
@@ -173,7 +166,6 @@ impl<'a> CompletionContext<'a> { | |||
173 | is_pat_or_const: None, | 166 | is_pat_or_const: None, |
174 | is_trivial_path: false, | 167 | is_trivial_path: false, |
175 | path_qual: None, | 168 | path_qual: None, |
176 | after_if: false, | ||
177 | can_be_stmt: false, | 169 | can_be_stmt: false, |
178 | is_expr: false, | 170 | is_expr: false, |
179 | is_new_item: false, | 171 | is_new_item: false, |
@@ -308,7 +300,14 @@ impl<'a> CompletionContext<'a> { | |||
308 | } | 300 | } |
309 | 301 | ||
310 | pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool { | 302 | pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool { |
311 | self.prev_sibling.is_some() | 303 | matches!( |
304 | self.prev_sibling, | ||
305 | Some(ImmediatePrevSibling::ImplDefType) | Some(ImmediatePrevSibling::TraitDefName) | ||
306 | ) | ||
307 | } | ||
308 | |||
309 | pub(crate) fn after_if(&self) -> bool { | ||
310 | matches!(self.prev_sibling, Some(ImmediatePrevSibling::IfExpr)) | ||
312 | } | 311 | } |
313 | 312 | ||
314 | pub(crate) fn is_path_disallowed(&self) -> bool { | 313 | pub(crate) fn is_path_disallowed(&self) -> bool { |
@@ -324,11 +323,6 @@ impl<'a> CompletionContext<'a> { | |||
324 | self.previous_token = previous_token(syntax_element.clone()); | 323 | self.previous_token = previous_token(syntax_element.clone()); |
325 | self.in_loop_body = is_in_loop_body(syntax_element.clone()); | 324 | self.in_loop_body = is_in_loop_body(syntax_element.clone()); |
326 | self.is_match_arm = is_match_arm(syntax_element.clone()); | 325 | self.is_match_arm = is_match_arm(syntax_element.clone()); |
327 | if has_prev_sibling(syntax_element.clone(), IMPL) { | ||
328 | self.prev_sibling = Some(PrevSibling::Impl) | ||
329 | } else if has_prev_sibling(syntax_element.clone(), TRAIT) { | ||
330 | self.prev_sibling = Some(PrevSibling::Trait) | ||
331 | } | ||
332 | 326 | ||
333 | self.mod_declaration_under_caret = | 327 | self.mod_declaration_under_caret = |
334 | find_node_at_offset::<ast::Module>(&file_with_fake_ident, offset) | 328 | find_node_at_offset::<ast::Module>(&file_with_fake_ident, offset) |
@@ -468,6 +462,7 @@ impl<'a> CompletionContext<'a> { | |||
468 | None => return, | 462 | None => return, |
469 | }; | 463 | }; |
470 | self.completion_location = determine_location(&name_like); | 464 | self.completion_location = determine_location(&name_like); |
465 | self.prev_sibling = determine_prev_sibling(&name_like); | ||
471 | match name_like { | 466 | match name_like { |
472 | ast::NameLike::Lifetime(lifetime) => { | 467 | ast::NameLike::Lifetime(lifetime) => { |
473 | self.classify_lifetime(original_file, lifetime, offset); | 468 | self.classify_lifetime(original_file, lifetime, offset); |
@@ -656,17 +651,6 @@ impl<'a> CompletionContext<'a> { | |||
656 | }) | 651 | }) |
657 | .unwrap_or(false); | 652 | .unwrap_or(false); |
658 | self.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some(); | 653 | self.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some(); |
659 | |||
660 | if let Some(off) = name_ref.syntax().text_range().start().checked_sub(2.into()) { | ||
661 | if let Some(if_expr) = | ||
662 | self.sema.find_node_at_offset_with_macros::<ast::IfExpr>(original_file, off) | ||
663 | { | ||
664 | if if_expr.syntax().text_range().end() < name_ref.syntax().text_range().start() | ||
665 | { | ||
666 | self.after_if = true; | ||
667 | } | ||
668 | } | ||
669 | } | ||
670 | } | 654 | } |
671 | 655 | ||
672 | if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { | 656 | if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { |