aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/context.rs
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-05-28 21:03:31 +0100
committerLukas Wirth <[email protected]>2021-05-28 21:03:31 +0100
commit47ad752e6cca5eb5499168ec7f859879e384a5ab (patch)
tree1f54d1080184735cffd2c6ee3891e94510c2eefe /crates/ide_completion/src/context.rs
parenta6b92a8cc00c4a4c451e6da2dd4e2a2e8e7bf749 (diff)
Implement prev sibling determination for `CompletionContext`
Diffstat (limited to 'crates/ide_completion/src/context.rs')
-rw-r--r--crates/ide_completion/src/context.rs40
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
18use crate::{ 18use 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)]
33pub(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()) {