about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2021-10-16 23:56:43 +0200
committerLukas Wirth <lukastw97@gmail.com>2021-10-16 23:56:57 +0200
commit81ccebf1f2ce237418ac15676bd72f46f8d59b01 (patch)
treefd4d0c28bd17fbc983618f99e0b70a3513d8b4b7
parent2fbd52c78f4f2aa38ef0b5e4cf9709fae2c918f1 (diff)
downloadrust-81ccebf1f2ce237418ac15676bd72f46f8d59b01.tar.gz
rust-81ccebf1f2ce237418ac15676bd72f46f8d59b01.zip
internal: Refactor lifetime completion context fields
-rw-r--r--crates/ide_completion/src/completions/lifetime.rs32
-rw-r--r--crates/ide_completion/src/context.rs56
2 files changed, 45 insertions, 43 deletions
diff --git a/crates/ide_completion/src/completions/lifetime.rs b/crates/ide_completion/src/completions/lifetime.rs
index 233bf51ec06..283dc021d6e 100644
--- a/crates/ide_completion/src/completions/lifetime.rs
+++ b/crates/ide_completion/src/completions/lifetime.rs
@@ -10,23 +10,27 @@
 use hir::ScopeDef;
 use syntax::ast;
 
-use crate::{completions::Completions, context::CompletionContext};
+use crate::{
+    completions::Completions,
+    context::{CompletionContext, LifetimeContext},
+};
 
 /// Completes lifetimes.
 pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext) {
-    if !ctx.lifetime_allowed {
-        return;
-    }
+    let lp = match &ctx.lifetime_ctx {
+        Some(LifetimeContext::Lifetime) => None,
+        Some(LifetimeContext::LifetimeParam(param)) => param.as_ref(),
+        _ => return,
+    };
     let lp_string;
-    let param_lifetime =
-        match (&ctx.name_syntax, ctx.lifetime_param_syntax.as_ref().and_then(|lp| lp.lifetime())) {
-            (Some(ast::NameLike::Lifetime(lt)), Some(lp)) if lp == lt.clone() => return,
-            (Some(_), Some(lp)) => {
-                lp_string = lp.to_string();
-                Some(&*lp_string)
-            }
-            _ => None,
-        };
+    let param_lifetime = match (&ctx.name_syntax, lp.and_then(|lp| lp.lifetime())) {
+        (Some(ast::NameLike::Lifetime(lt)), Some(lp)) if lp == lt.clone() => return,
+        (Some(_), Some(lp)) => {
+            lp_string = lp.to_string();
+            Some(&*lp_string)
+        }
+        _ => None,
+    };
 
     ctx.scope.process_all_names(&mut |name, res| {
         if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res {
@@ -42,7 +46,7 @@ pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext)
 
 /// Completes labels.
 pub(crate) fn complete_label(acc: &mut Completions, ctx: &CompletionContext) {
-    if !ctx.is_label_ref {
+    if !matches!(ctx.lifetime_ctx, Some(LifetimeContext::LabelRef)) {
         return;
     }
     ctx.scope.process_all_names(&mut |name, res| {
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index b75277f628e..25da46f1d7e 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -60,6 +60,14 @@ pub(super) struct PatternContext {
     pub(super) is_param: Option<ParamKind>,
 }
 
+#[derive(Debug)]
+pub(super) enum LifetimeContext {
+    LifetimeParam(Option<ast::LifetimeParam>),
+    Lifetime,
+    LabelRef,
+    LabelDef,
+}
+
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub(crate) enum CallKind {
     Pat,
@@ -96,16 +104,12 @@ pub(crate) struct CompletionContext<'a> {
     pub(super) impl_def: Option<ast::Impl>,
     pub(super) name_syntax: Option<ast::NameLike>,
 
-    // potentially set if we are completing a lifetime
-    pub(super) lifetime_param_syntax: Option<ast::LifetimeParam>,
-    pub(super) lifetime_allowed: bool,
-    pub(super) is_label_ref: bool,
-
     pub(super) completion_location: Option<ImmediateLocation>,
     pub(super) prev_sibling: Option<ImmediatePrevSibling>,
     pub(super) attribute_under_caret: Option<ast::Attr>,
     pub(super) previous_token: Option<SyntaxToken>,
 
+    pub(super) lifetime_ctx: Option<LifetimeContext>,
     pub(super) pattern_ctx: Option<PatternContext>,
     pub(super) path_context: Option<PathCompletionContext>,
     pub(super) locals: Vec<(String, Local)>,
@@ -161,9 +165,7 @@ impl<'a> CompletionContext<'a> {
             function_def: None,
             impl_def: None,
             name_syntax: None,
-            lifetime_param_syntax: None,
-            lifetime_allowed: false,
-            is_label_ref: false,
+            lifetime_ctx: None,
             pattern_ctx: None,
             completion_location: None,
             prev_sibling: None,
@@ -294,8 +296,14 @@ impl<'a> CompletionContext<'a> {
         self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind)
     }
 
-    pub(crate) fn expects_assoc_item(&self) -> bool {
-        matches!(self.completion_location, Some(ImmediateLocation::Trait | ImmediateLocation::Impl))
+    pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> {
+        match &self.completion_location {
+            Some(
+                ImmediateLocation::MethodCall { receiver, .. }
+                | ImmediateLocation::FieldAccess { receiver, .. },
+            ) => receiver.as_ref(),
+            _ => None,
+        }
     }
 
     pub(crate) fn has_dot_receiver(&self) -> bool {
@@ -306,14 +314,8 @@ impl<'a> CompletionContext<'a> {
         )
     }
 
-    pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> {
-        match &self.completion_location {
-            Some(
-                ImmediateLocation::MethodCall { receiver, .. }
-                | ImmediateLocation::FieldAccess { receiver, .. },
-            ) => receiver.as_ref(),
-            _ => None,
-        }
+    pub(crate) fn expects_assoc_item(&self) -> bool {
+        matches!(self.completion_location, Some(ImmediateLocation::Trait | ImmediateLocation::Impl))
     }
 
     pub(crate) fn expects_non_trait_assoc_item(&self) -> bool {
@@ -676,19 +678,15 @@ impl<'a> CompletionContext<'a> {
                 return;
             }
 
-            match_ast! {
+            self.lifetime_ctx = Some(match_ast! {
                 match parent {
-                    ast::LifetimeParam(_it) => {
-                        self.lifetime_allowed = true;
-                        self.lifetime_param_syntax =
-                            self.sema.find_node_at_offset_with_macros(original_file, offset);
-                    },
-                    ast::BreakExpr(_it) => self.is_label_ref = true,
-                    ast::ContinueExpr(_it) => self.is_label_ref = true,
-                    ast::Label(_it) => (),
-                    _ => self.lifetime_allowed = true,
+                    ast::LifetimeParam(_it) => LifetimeContext::LifetimeParam(self.sema.find_node_at_offset_with_macros(original_file, offset)),
+                    ast::BreakExpr(_it) => LifetimeContext::LabelRef,
+                    ast::ContinueExpr(_it) => LifetimeContext::LabelRef,
+                    ast::Label(_it) => LifetimeContext::LabelDef,
+                    _ => LifetimeContext::Lifetime,
                 }
-            }
+            });
         }
     }