mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 22:54:58 +00:00
Move CompletionContext::incomplete_let
into PathKind::Expr
This commit is contained in:
parent
7369e5120d
commit
83e8f3ac30
4 changed files with 29 additions and 12 deletions
|
@ -110,12 +110,18 @@ impl Completions {
|
||||||
["self", "super", "crate"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
|
["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);
|
let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw);
|
||||||
|
|
||||||
match ctx.config.snippet_cap {
|
match ctx.config.snippet_cap {
|
||||||
Some(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
|
// complete block expression snippets with a trailing semicolon, if inside an incomplete let
|
||||||
cov_mark::hit!(let_semi);
|
cov_mark::hit!(let_semi);
|
||||||
item.insert_snippet(cap, format!("{};", snippet));
|
item.insert_snippet(cap, format!("{};", snippet));
|
||||||
|
@ -130,6 +136,16 @@ impl Completions {
|
||||||
item.add_to(self);
|
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) {
|
pub(crate) fn add_crate_roots(&mut self, ctx: &CompletionContext) {
|
||||||
ctx.process_all_names(&mut |name, res| match res {
|
ctx.process_all_names(&mut |name, res| match res {
|
||||||
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root(ctx.db) => {
|
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root(ctx.db) => {
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub(crate) fn complete_expr_path(
|
||||||
wants_mut_token,
|
wants_mut_token,
|
||||||
in_condition,
|
in_condition,
|
||||||
ty,
|
ty,
|
||||||
|
incomplete_let,
|
||||||
) = match path_ctx {
|
) = match path_ctx {
|
||||||
&PathCompletionCtx {
|
&PathCompletionCtx {
|
||||||
kind:
|
kind:
|
||||||
|
@ -34,6 +35,7 @@ pub(crate) fn complete_expr_path(
|
||||||
in_loop_body,
|
in_loop_body,
|
||||||
after_if_expr,
|
after_if_expr,
|
||||||
in_condition,
|
in_condition,
|
||||||
|
incomplete_let,
|
||||||
ref ref_expr_parent,
|
ref ref_expr_parent,
|
||||||
ref is_func_update,
|
ref is_func_update,
|
||||||
ref innermost_ret_ty,
|
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),
|
ref_expr_parent.as_ref().map(|it| it.mut_token().is_none()).unwrap_or(false),
|
||||||
in_condition,
|
in_condition,
|
||||||
innermost_ret_ty,
|
innermost_ret_ty,
|
||||||
|
incomplete_let,
|
||||||
),
|
),
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
@ -220,7 +223,8 @@ pub(crate) fn complete_expr_path(
|
||||||
});
|
});
|
||||||
|
|
||||||
if !is_func_update {
|
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 {
|
if !in_block_expr {
|
||||||
add_keyword("unsafe", "unsafe {\n $0\n}");
|
add_keyword("unsafe", "unsafe {\n $0\n}");
|
||||||
|
|
|
@ -93,6 +93,7 @@ pub(super) enum PathKind {
|
||||||
after_if_expr: bool,
|
after_if_expr: bool,
|
||||||
/// Whether this expression is the direct condition of an if or while expression
|
/// Whether this expression is the direct condition of an if or while expression
|
||||||
in_condition: bool,
|
in_condition: bool,
|
||||||
|
incomplete_let: bool,
|
||||||
ref_expr_parent: Option<ast::RefExpr>,
|
ref_expr_parent: Option<ast::RefExpr>,
|
||||||
is_func_update: Option<ast::RecordExpr>,
|
is_func_update: Option<ast::RecordExpr>,
|
||||||
self_param: Option<hir::SelfParam>,
|
self_param: Option<hir::SelfParam>,
|
||||||
|
@ -322,9 +323,6 @@ pub(crate) struct CompletionContext<'a> {
|
||||||
/// The parent impl of the cursor position if it exists.
|
/// The parent impl of the cursor position if it exists.
|
||||||
// FIXME: This probably doesn't belong here
|
// FIXME: This probably doesn't belong here
|
||||||
pub(super) impl_def: Option<ast::Impl>,
|
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
|
// FIXME: This shouldn't exist
|
||||||
pub(super) previous_token: Option<SyntaxToken>,
|
pub(super) previous_token: Option<SyntaxToken>,
|
||||||
|
@ -500,7 +498,6 @@ impl<'a> CompletionContext<'a> {
|
||||||
expected_name: None,
|
expected_name: None,
|
||||||
expected_type: None,
|
expected_type: None,
|
||||||
impl_def: None,
|
impl_def: None,
|
||||||
incomplete_let: false,
|
|
||||||
previous_token: None,
|
previous_token: None,
|
||||||
// dummy value, will be overwritten
|
// dummy value, will be overwritten
|
||||||
ident_ctx: IdentContext::UnexpandedAttrTT { fake_attribute_under_caret: None },
|
ident_ctx: IdentContext::UnexpandedAttrTT { fake_attribute_under_caret: None },
|
||||||
|
|
|
@ -330,11 +330,6 @@ impl<'a> CompletionContext<'a> {
|
||||||
self.previous_token =
|
self.previous_token =
|
||||||
syntax_element.clone().into_token().and_then(previous_non_trivia_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();
|
(self.expected_type, self.expected_name) = self.expected_type_and_name();
|
||||||
|
|
||||||
// Overwrite the path kind for derives
|
// Overwrite the path kind for derives
|
||||||
|
@ -767,6 +762,10 @@ impl<'a> CompletionContext<'a> {
|
||||||
};
|
};
|
||||||
let is_func_update = func_update_record(it);
|
let is_func_update = func_update_record(it);
|
||||||
let in_condition = is_in_condition(&expr);
|
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 {
|
PathKind::Expr {
|
||||||
in_block_expr,
|
in_block_expr,
|
||||||
|
@ -777,6 +776,7 @@ impl<'a> CompletionContext<'a> {
|
||||||
is_func_update,
|
is_func_update,
|
||||||
innermost_ret_ty,
|
innermost_ret_ty,
|
||||||
self_param,
|
self_param,
|
||||||
|
incomplete_let,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let make_path_kind_type = |ty: ast::Type| {
|
let make_path_kind_type = |ty: ast::Type| {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue