aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/context.rs
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-06-17 12:56:55 +0100
committerLukas Wirth <[email protected]>2021-06-17 12:56:55 +0100
commit2225db2eb48bd8c8fdf399c50652d3f95c851ace (patch)
tree31a419449dff7bb0112ae328de2e4fdec755326d /crates/ide_completion/src/context.rs
parente14f5cfff04942f45a4af3b45152df9672b3458a (diff)
Refine `self`, `super` and `crate` completion in use paths
Diffstat (limited to 'crates/ide_completion/src/context.rs')
-rw-r--r--crates/ide_completion/src/context.rs26
1 files changed, 16 insertions, 10 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 121909857..c3076f608 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,7 +264,7 @@ impl<'a> CompletionContext<'a> {
264 } 264 }
265 } 265 }
266 266
267 pub(crate) fn expects_use_tree(&self) -> bool { 267 pub(crate) fn expects_new_use_tree(&self) -> bool {
268 matches!(self.completion_location, Some(ImmediateLocation::Use)) 268 matches!(self.completion_location, Some(ImmediateLocation::Use))
269 } 269 }
270 270
@@ -295,6 +295,13 @@ impl<'a> CompletionContext<'a> {
295 matches!(self.completion_location, Some(ImmediateLocation::RecordField)) 295 matches!(self.completion_location, Some(ImmediateLocation::RecordField))
296 } 296 }
297 297
298 pub(crate) fn in_use_tree(&self) -> bool {
299 matches!(
300 self.completion_location,
301 Some(ImmediateLocation::Use) | Some(ImmediateLocation::UseTree)
302 )
303 }
304
298 pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool { 305 pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool {
299 matches!( 306 matches!(
300 self.prev_sibling, 307 self.prev_sibling,
@@ -578,9 +585,6 @@ impl<'a> CompletionContext<'a> {
578 self.name_ref_syntax = 585 self.name_ref_syntax =
579 find_node_at_offset(original_file, name_ref.syntax().text_range().start()); 586 find_node_at_offset(original_file, name_ref.syntax().text_range().start());
580 587
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 588 self.function_def = self
585 .sema 589 .sema
586 .token_ancestors_with_macros(self.token.clone()) 590 .token_ancestors_with_macros(self.token.clone())
@@ -600,6 +604,7 @@ impl<'a> CompletionContext<'a> {
600 has_type_args: false, 604 has_type_args: false,
601 can_be_stmt: false, 605 can_be_stmt: false,
602 in_loop_body: false, 606 in_loop_body: false,
607 use_tree_parent: false,
603 kind: None, 608 kind: None,
604 }); 609 });
605 path_ctx.in_loop_body = is_in_loop_body(name_ref.syntax()); 610 path_ctx.in_loop_body = is_in_loop_body(name_ref.syntax());
@@ -627,7 +632,8 @@ impl<'a> CompletionContext<'a> {
627 } 632 }
628 path_ctx.has_type_args = segment.generic_arg_list().is_some(); 633 path_ctx.has_type_args = segment.generic_arg_list().is_some();
629 634
630 if let Some(path) = path_or_use_tree_qualifier(&path) { 635 if let Some((path, use_tree_parent)) = path_or_use_tree_qualifier(&path) {
636 path_ctx.use_tree_parent = use_tree_parent;
631 path_ctx.qualifier = path 637 path_ctx.qualifier = path
632 .segment() 638 .segment()
633 .and_then(|it| { 639 .and_then(|it| {
@@ -681,13 +687,13 @@ fn is_node<N: AstNode>(node: &SyntaxNode) -> bool {
681 } 687 }
682} 688}
683 689
684fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<ast::Path> { 690fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> {
685 if let Some(qual) = path.qualifier() { 691 if let Some(qual) = path.qualifier() {
686 return Some(qual); 692 return Some((qual, false));
687 } 693 }
688 let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?; 694 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)?; 695 let use_tree = use_tree_list.syntax().parent().and_then(ast::UseTree::cast)?;
690 use_tree.path() 696 use_tree.path().zip(Some(true))
691} 697}
692 698
693#[cfg(test)] 699#[cfg(test)]