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.rs28
1 files changed, 15 insertions, 13 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 121909857..240cac1de 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -43,6 +43,8 @@ pub(crate) struct PathCompletionContext {
43 pub(super) is_trivial_path: bool, 43 pub(super) is_trivial_path: bool,
44 /// If not a trivial path, the prefix (qualifier). 44 /// If not a trivial path, the prefix (qualifier).
45 pub(super) qualifier: Option<ast::Path>, 45 pub(super) qualifier: Option<ast::Path>,
46 /// Whether the qualifier comes from a use tree parent or not
47 pub(super) use_tree_parent: bool,
46 pub(super) kind: Option<PathKind>, 48 pub(super) kind: Option<PathKind>,
47 /// Whether the path segment has type args or not. 49 /// Whether the path segment has type args or not.
48 pub(super) has_type_args: bool, 50 pub(super) has_type_args: bool,
@@ -79,7 +81,6 @@ pub(crate) struct CompletionContext<'a> {
79 /// The parent impl of the cursor position if it exists. 81 /// The parent impl of the cursor position if it exists.
80 pub(super) impl_def: Option<ast::Impl>, 82 pub(super) impl_def: Option<ast::Impl>,
81 pub(super) name_ref_syntax: Option<ast::NameRef>, 83 pub(super) name_ref_syntax: Option<ast::NameRef>,
82 pub(super) use_item_syntax: Option<ast::Use>,
83 84
84 // potentially set if we are completing a lifetime 85 // potentially set if we are completing a lifetime
85 pub(super) lifetime_syntax: Option<ast::Lifetime>, 86 pub(super) lifetime_syntax: Option<ast::Lifetime>,
@@ -151,7 +152,6 @@ impl<'a> CompletionContext<'a> {
151 function_def: None, 152 function_def: None,
152 impl_def: None, 153 impl_def: None,
153 name_ref_syntax: None, 154 name_ref_syntax: None,
154 use_item_syntax: None,
155 lifetime_syntax: None, 155 lifetime_syntax: None,
156 lifetime_param_syntax: None, 156 lifetime_param_syntax: None,
157 lifetime_allowed: false, 157 lifetime_allowed: false,
@@ -264,10 +264,6 @@ impl<'a> CompletionContext<'a> {
264 } 264 }
265 } 265 }
266 266
267 pub(crate) fn expects_use_tree(&self) -> bool {
268 matches!(self.completion_location, Some(ImmediateLocation::Use))
269 }
270
271 pub(crate) fn expects_non_trait_assoc_item(&self) -> bool { 267 pub(crate) fn expects_non_trait_assoc_item(&self) -> bool {
272 matches!(self.completion_location, Some(ImmediateLocation::Impl)) 268 matches!(self.completion_location, Some(ImmediateLocation::Impl))
273 } 269 }
@@ -295,6 +291,13 @@ impl<'a> CompletionContext<'a> {
295 matches!(self.completion_location, Some(ImmediateLocation::RecordField)) 291 matches!(self.completion_location, Some(ImmediateLocation::RecordField))
296 } 292 }
297 293
294 pub(crate) fn in_use_tree(&self) -> bool {
295 matches!(
296 self.completion_location,
297 Some(ImmediateLocation::Use) | Some(ImmediateLocation::UseTree)
298 )
299 }
300
298 pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool { 301 pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool {
299 matches!( 302 matches!(
300 self.prev_sibling, 303 self.prev_sibling,
@@ -578,9 +581,6 @@ impl<'a> CompletionContext<'a> {
578 self.name_ref_syntax = 581 self.name_ref_syntax =
579 find_node_at_offset(original_file, name_ref.syntax().text_range().start()); 582 find_node_at_offset(original_file, name_ref.syntax().text_range().start());
580 583
581 self.use_item_syntax =
582 self.sema.token_ancestors_with_macros(self.token.clone()).find_map(ast::Use::cast);
583
584 self.function_def = self 584 self.function_def = self
585 .sema 585 .sema
586 .token_ancestors_with_macros(self.token.clone()) 586 .token_ancestors_with_macros(self.token.clone())
@@ -600,6 +600,7 @@ impl<'a> CompletionContext<'a> {
600 has_type_args: false, 600 has_type_args: false,
601 can_be_stmt: false, 601 can_be_stmt: false,
602 in_loop_body: false, 602 in_loop_body: false,
603 use_tree_parent: false,
603 kind: None, 604 kind: None,
604 }); 605 });
605 path_ctx.in_loop_body = is_in_loop_body(name_ref.syntax()); 606 path_ctx.in_loop_body = is_in_loop_body(name_ref.syntax());
@@ -627,7 +628,8 @@ impl<'a> CompletionContext<'a> {
627 } 628 }
628 path_ctx.has_type_args = segment.generic_arg_list().is_some(); 629 path_ctx.has_type_args = segment.generic_arg_list().is_some();
629 630
630 if let Some(path) = path_or_use_tree_qualifier(&path) { 631 if let Some((path, use_tree_parent)) = path_or_use_tree_qualifier(&path) {
632 path_ctx.use_tree_parent = use_tree_parent;
631 path_ctx.qualifier = path 633 path_ctx.qualifier = path
632 .segment() 634 .segment()
633 .and_then(|it| { 635 .and_then(|it| {
@@ -681,13 +683,13 @@ fn is_node<N: AstNode>(node: &SyntaxNode) -> bool {
681 } 683 }
682} 684}
683 685
684fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<ast::Path> { 686fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> {
685 if let Some(qual) = path.qualifier() { 687 if let Some(qual) = path.qualifier() {
686 return Some(qual); 688 return Some((qual, false));
687 } 689 }
688 let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?; 690 let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
689 let use_tree = use_tree_list.syntax().parent().and_then(ast::UseTree::cast)?; 691 let use_tree = use_tree_list.syntax().parent().and_then(ast::UseTree::cast)?;
690 use_tree.path() 692 use_tree.path().zip(Some(true))
691} 693}
692 694
693#[cfg(test)] 695#[cfg(test)]