]> git.lizzy.rs Git - rust.git/commitdiff
internal: Refactor lifetime completion context fields
authorLukas Wirth <lukastw97@gmail.com>
Sat, 16 Oct 2021 21:56:43 +0000 (23:56 +0200)
committerLukas Wirth <lukastw97@gmail.com>
Sat, 16 Oct 2021 21:56:57 +0000 (23:56 +0200)
crates/ide_completion/src/completions/lifetime.rs
crates/ide_completion/src/context.rs

index 233bf51ec06bef4f56550b5a7b581355a9b85976..283dc021d6ecb0c71339ded36c8ce09d35c5546f 100644 (file)
 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| {
index b75277f628ea463aa4eaa55d078717405e7ddf50..25da46f1d7e00d3cc95338532539c983e043348b 100644 (file)
@@ -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 @@ pub(super) fn new(
             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 @@ pub(crate) fn previous_token_is(&self, kind: SyntaxKind) -> bool {
         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 @@ pub(crate) fn has_dot_receiver(&self) -> bool {
         )
     }
 
-    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 @@ fn classify_lifetime(
                 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,
                 }
-            }
+            });
         }
     }