about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2022-06-18 10:18:56 +0200
committerLukas Wirth <lukastw97@gmail.com>2022-06-18 10:19:04 +0200
commit83e8f3ac308aab3c51158c6a27491a4e8796f361 (patch)
tree2cfc4633808f7bcfaea26b74d5f18b65005fcfee
parent7369e5120d88ca0c75d32a6ca3558b64351a6858 (diff)
downloadrust-83e8f3ac308aab3c51158c6a27491a4e8796f361.tar.gz
rust-83e8f3ac308aab3c51158c6a27491a4e8796f361.zip
Move `CompletionContext::incomplete_let` into `PathKind::Expr`
-rw-r--r--crates/ide-completion/src/completions.rs20
-rw-r--r--crates/ide-completion/src/completions/expr.rs6
-rw-r--r--crates/ide-completion/src/context.rs5
-rw-r--r--crates/ide-completion/src/context/analysis.rs10
4 files changed, 29 insertions, 12 deletions
diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs
index b0763584432..f8747b07249 100644
--- a/crates/ide-completion/src/completions.rs
+++ b/crates/ide-completion/src/completions.rs
@@ -110,12 +110,18 @@ impl Completions {
         ["self", "super", "crate"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
     }
 
-    pub(crate) fn add_keyword_snippet(&mut self, ctx: &CompletionContext, kw: &str, snippet: &str) {
+    pub(crate) fn add_keyword_snippet_expr(
+        &mut self,
+        ctx: &CompletionContext,
+        kw: &str,
+        snippet: &str,
+        incomplete_let: bool,
+    ) {
         let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw);
 
         match ctx.config.snippet_cap {
             Some(cap) => {
-                if snippet.ends_with('}') && ctx.incomplete_let {
+                if snippet.ends_with('}') && incomplete_let {
                     // complete block expression snippets with a trailing semicolon, if inside an incomplete let
                     cov_mark::hit!(let_semi);
                     item.insert_snippet(cap, format!("{};", snippet));
@@ -130,6 +136,16 @@ impl Completions {
         item.add_to(self);
     }
 
+    pub(crate) fn add_keyword_snippet(&mut self, ctx: &CompletionContext, kw: &str, snippet: &str) {
+        let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw);
+
+        match ctx.config.snippet_cap {
+            Some(cap) => item.insert_snippet(cap, snippet),
+            None => item.insert_text(if snippet.contains('$') { kw } else { snippet }),
+        };
+        item.add_to(self);
+    }
+
     pub(crate) fn add_crate_roots(&mut self, ctx: &CompletionContext) {
         ctx.process_all_names(&mut |name, res| match res {
             ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root(ctx.db) => {
diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs
index ecc1442bfc7..e4d1c290c07 100644
--- a/crates/ide-completion/src/completions/expr.rs
+++ b/crates/ide-completion/src/completions/expr.rs
@@ -26,6 +26,7 @@ pub(crate) fn complete_expr_path(
         wants_mut_token,
         in_condition,
         ty,
+        incomplete_let,
     ) = match path_ctx {
         &PathCompletionCtx {
             kind:
@@ -34,6 +35,7 @@ pub(crate) fn complete_expr_path(
                     in_loop_body,
                     after_if_expr,
                     in_condition,
+                    incomplete_let,
                     ref ref_expr_parent,
                     ref is_func_update,
                     ref innermost_ret_ty,
@@ -50,6 +52,7 @@ pub(crate) fn complete_expr_path(
             ref_expr_parent.as_ref().map(|it| it.mut_token().is_none()).unwrap_or(false),
             in_condition,
             innermost_ret_ty,
+            incomplete_let,
         ),
         _ => return,
     };
@@ -220,7 +223,8 @@ pub(crate) fn complete_expr_path(
             });
 
             if !is_func_update {
-                let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
+                let mut add_keyword =
+                    |kw, snippet| acc.add_keyword_snippet_expr(ctx, kw, snippet, incomplete_let);
 
                 if !in_block_expr {
                     add_keyword("unsafe", "unsafe {\n    $0\n}");
diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs
index 7df9b4921af..bc2c2fc7132 100644
--- a/crates/ide-completion/src/context.rs
+++ b/crates/ide-completion/src/context.rs
@@ -93,6 +93,7 @@ pub(super) enum PathKind {
         after_if_expr: bool,
         /// Whether this expression is the direct condition of an if or while expression
         in_condition: bool,
+        incomplete_let: bool,
         ref_expr_parent: Option<ast::RefExpr>,
         is_func_update: Option<ast::RecordExpr>,
         self_param: Option<hir::SelfParam>,
@@ -322,9 +323,6 @@ pub(crate) struct CompletionContext<'a> {
     /// The parent impl of the cursor position if it exists.
     // FIXME: This probably doesn't belong here
     pub(super) impl_def: Option<ast::Impl>,
-    /// Are we completing inside a let statement with a missing semicolon?
-    // FIXME: This should be part of PathKind::Expr
-    pub(super) incomplete_let: bool,
 
     // FIXME: This shouldn't exist
     pub(super) previous_token: Option<SyntaxToken>,
@@ -500,7 +498,6 @@ impl<'a> CompletionContext<'a> {
             expected_name: None,
             expected_type: None,
             impl_def: None,
-            incomplete_let: false,
             previous_token: None,
             // dummy value, will be overwritten
             ident_ctx: IdentContext::UnexpandedAttrTT { fake_attribute_under_caret: None },
diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs
index 4f65ae402e2..d416d8251d7 100644
--- a/crates/ide-completion/src/context/analysis.rs
+++ b/crates/ide-completion/src/context/analysis.rs
@@ -330,11 +330,6 @@ impl<'a> CompletionContext<'a> {
         self.previous_token =
             syntax_element.clone().into_token().and_then(previous_non_trivia_token);
 
-        self.incomplete_let =
-            syntax_element.ancestors().take(6).find_map(ast::LetStmt::cast).map_or(false, |it| {
-                it.syntax().text_range().end() == syntax_element.text_range().end()
-            });
-
         (self.expected_type, self.expected_name) = self.expected_type_and_name();
 
         // Overwrite the path kind for derives
@@ -767,6 +762,10 @@ impl<'a> CompletionContext<'a> {
             };
             let is_func_update = func_update_record(it);
             let in_condition = is_in_condition(&expr);
+            let incomplete_let = it
+                .parent()
+                .and_then(ast::LetStmt::cast)
+                .map_or(false, |it| it.semicolon_token().is_none());
 
             PathKind::Expr {
                 in_block_expr,
@@ -777,6 +776,7 @@ impl<'a> CompletionContext<'a> {
                 is_func_update,
                 innermost_ret_ty,
                 self_param,
+                incomplete_let,
             }
         };
         let make_path_kind_type = |ty: ast::Type| {