mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
Merge #9899
9899: minor: Simplify r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
01de9021cd
5 changed files with 70 additions and 58 deletions
|
@ -7,8 +7,8 @@ use syntax::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::ParamKind, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind,
|
context::{ParamKind, PatternContext},
|
||||||
Completions,
|
CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Complete repeated parameters, both name and type. For example, if all
|
/// Complete repeated parameters, both name and type. For example, if all
|
||||||
|
@ -16,7 +16,8 @@ use crate::{
|
||||||
/// `spam: &mut Spam` insert text/label and `spam` lookup string will be
|
/// `spam: &mut Spam` insert text/label and `spam` lookup string will be
|
||||||
/// suggested.
|
/// suggested.
|
||||||
pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
|
pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
|
||||||
if ctx.is_param != Some(ParamKind::Function) {
|
if !matches!(ctx.pattern_ctx, Some(PatternContext { is_param: Some(ParamKind::Function), .. }))
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
//! Completes constants and paths in patterns.
|
//! Completes constants and paths in patterns.
|
||||||
|
|
||||||
use crate::{context::PatternRefutability, CompletionContext, Completions};
|
use crate::{
|
||||||
|
context::{PatternContext, PatternRefutability},
|
||||||
|
CompletionContext, Completions,
|
||||||
|
};
|
||||||
|
|
||||||
/// Completes constants and paths in patterns.
|
/// Completes constants and paths in patterns.
|
||||||
pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
let refutable = match ctx.is_pat_or_const {
|
let refutable = match ctx.pattern_ctx {
|
||||||
Some(it) => it == PatternRefutability::Refutable,
|
Some(PatternContext { refutability, .. }) => refutability == PatternRefutability::Refutable,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,12 @@ pub(crate) struct PathCompletionContext {
|
||||||
pub(super) in_loop_body: bool,
|
pub(super) in_loop_body: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(super) struct PatternContext {
|
||||||
|
pub(super) refutability: PatternRefutability,
|
||||||
|
pub(super) is_param: Option<ParamKind>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub(crate) enum CallKind {
|
pub(crate) enum CallKind {
|
||||||
Pat,
|
Pat,
|
||||||
|
@ -95,15 +101,12 @@ pub(crate) struct CompletionContext<'a> {
|
||||||
pub(super) lifetime_allowed: bool,
|
pub(super) lifetime_allowed: bool,
|
||||||
pub(super) is_label_ref: bool,
|
pub(super) is_label_ref: bool,
|
||||||
|
|
||||||
// potentially set if we are completing a name
|
|
||||||
pub(super) is_pat_or_const: Option<PatternRefutability>,
|
|
||||||
pub(super) is_param: Option<ParamKind>,
|
|
||||||
|
|
||||||
pub(super) completion_location: Option<ImmediateLocation>,
|
pub(super) completion_location: Option<ImmediateLocation>,
|
||||||
pub(super) prev_sibling: Option<ImmediatePrevSibling>,
|
pub(super) prev_sibling: Option<ImmediatePrevSibling>,
|
||||||
pub(super) attribute_under_caret: Option<ast::Attr>,
|
pub(super) attribute_under_caret: Option<ast::Attr>,
|
||||||
pub(super) previous_token: Option<SyntaxToken>,
|
pub(super) previous_token: Option<SyntaxToken>,
|
||||||
|
|
||||||
|
pub(super) pattern_ctx: Option<PatternContext>,
|
||||||
pub(super) path_context: Option<PathCompletionContext>,
|
pub(super) path_context: Option<PathCompletionContext>,
|
||||||
pub(super) active_parameter: Option<ActiveParameter>,
|
pub(super) active_parameter: Option<ActiveParameter>,
|
||||||
pub(super) locals: Vec<(String, Local)>,
|
pub(super) locals: Vec<(String, Local)>,
|
||||||
|
@ -163,8 +166,7 @@ impl<'a> CompletionContext<'a> {
|
||||||
lifetime_param_syntax: None,
|
lifetime_param_syntax: None,
|
||||||
lifetime_allowed: false,
|
lifetime_allowed: false,
|
||||||
is_label_ref: false,
|
is_label_ref: false,
|
||||||
is_pat_or_const: None,
|
pattern_ctx: None,
|
||||||
is_param: None,
|
|
||||||
completion_location: None,
|
completion_location: None,
|
||||||
prev_sibling: None,
|
prev_sibling: None,
|
||||||
attribute_under_caret: None,
|
attribute_under_caret: None,
|
||||||
|
@ -642,50 +644,51 @@ impl<'a> CompletionContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn classify_name(&mut self, name: ast::Name) {
|
fn classify_name(&mut self, name: ast::Name) {
|
||||||
if let Some(bind_pat) = name.syntax().parent().and_then(ast::IdentPat::cast) {
|
self.fill_impl_def();
|
||||||
self.is_pat_or_const = Some(PatternRefutability::Refutable);
|
|
||||||
if !bind_pat.is_simple_ident() {
|
|
||||||
self.is_pat_or_const = None;
|
|
||||||
} else {
|
|
||||||
let irrefutable_pat = bind_pat.syntax().ancestors().find_map(|node| {
|
|
||||||
match_ast! {
|
|
||||||
match node {
|
|
||||||
ast::LetStmt(it) => Some(it.pat()),
|
|
||||||
ast::Param(it) => Some(it.pat()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if let Some(Some(pat)) = irrefutable_pat {
|
|
||||||
// This check is here since we could be inside a pattern in the initializer expression of the let statement.
|
|
||||||
if pat.syntax().text_range().contains_range(bind_pat.syntax().text_range()) {
|
|
||||||
self.is_pat_or_const = Some(PatternRefutability::Irrefutable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if let Some(bind_pat) = name.syntax().parent().and_then(ast::IdentPat::cast) {
|
||||||
let is_name_in_field_pat = bind_pat
|
let is_name_in_field_pat = bind_pat
|
||||||
.syntax()
|
.syntax()
|
||||||
.parent()
|
.parent()
|
||||||
.and_then(ast::RecordPatField::cast)
|
.and_then(ast::RecordPatField::cast)
|
||||||
.map_or(false, |pat_field| pat_field.name_ref().is_none());
|
.map_or(false, |pat_field| pat_field.name_ref().is_none());
|
||||||
if is_name_in_field_pat {
|
if is_name_in_field_pat {
|
||||||
self.is_pat_or_const = None;
|
return;
|
||||||
}
|
}
|
||||||
}
|
if bind_pat.is_simple_ident() {
|
||||||
|
let mut is_param = None;
|
||||||
self.fill_impl_def();
|
let refutability = bind_pat
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(param) = name
|
|
||||||
.syntax()
|
.syntax()
|
||||||
.ancestors()
|
.ancestors()
|
||||||
.find_map(ast::Param::cast)
|
.skip_while(|it| ast::Pat::can_cast(it.kind()))
|
||||||
.filter(|it| it.syntax().text_range() == name.syntax().text_range())
|
.next()
|
||||||
{
|
.map_or(PatternRefutability::Irrefutable, |node| {
|
||||||
let is_closure_param =
|
match_ast! {
|
||||||
param.syntax().ancestors().nth(2).and_then(ast::ClosureExpr::cast).is_some();
|
match node {
|
||||||
self.is_param =
|
ast::LetStmt(__) => PatternRefutability::Irrefutable,
|
||||||
Some(if is_closure_param { ParamKind::Closure } else { ParamKind::Function });
|
ast::Param(param) => {
|
||||||
|
let is_closure_param = param
|
||||||
|
.syntax()
|
||||||
|
.ancestors()
|
||||||
|
.nth(2)
|
||||||
|
.and_then(ast::ClosureExpr::cast)
|
||||||
|
.is_some();
|
||||||
|
is_param = Some(if is_closure_param {
|
||||||
|
ParamKind::Closure
|
||||||
|
} else {
|
||||||
|
ParamKind::Function
|
||||||
|
});
|
||||||
|
PatternRefutability::Irrefutable
|
||||||
|
},
|
||||||
|
ast::MatchArm(__) => PatternRefutability::Refutable,
|
||||||
|
ast::Condition(__) => PatternRefutability::Refutable,
|
||||||
|
ast::ForExpr(__) => PatternRefutability::Irrefutable,
|
||||||
|
_ => PatternRefutability::Irrefutable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.pattern_ctx = Some(PatternContext { refutability, is_param });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,7 @@ fn render_resolution_(
|
||||||
hir::ScopeDef::ModuleDef(Function(func)) => {
|
hir::ScopeDef::ModuleDef(Function(func)) => {
|
||||||
return render_fn(ctx, import_to_add, Some(local_name), *func);
|
return render_fn(ctx, import_to_add, Some(local_name), *func);
|
||||||
}
|
}
|
||||||
hir::ScopeDef::ModuleDef(Variant(_)) if ctx.completion.is_pat_or_const.is_some() => {
|
hir::ScopeDef::ModuleDef(Variant(_)) if ctx.completion.pattern_ctx.is_some() => {
|
||||||
CompletionItemKind::SymbolKind(SymbolKind::Variant)
|
CompletionItemKind::SymbolKind(SymbolKind::Variant)
|
||||||
}
|
}
|
||||||
hir::ScopeDef::ModuleDef(Variant(var)) => {
|
hir::ScopeDef::ModuleDef(Variant(var)) => {
|
||||||
|
|
|
@ -5,8 +5,10 @@ use ide_db::helpers::SnippetCap;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::ParamKind, item::CompletionKind, render::RenderContext, CompletionItem,
|
context::{ParamKind, PatternContext},
|
||||||
CompletionItemKind,
|
item::CompletionKind,
|
||||||
|
render::RenderContext,
|
||||||
|
CompletionItem, CompletionItemKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) fn render_struct_pat(
|
pub(crate) fn render_struct_pat(
|
||||||
|
@ -86,7 +88,10 @@ fn render_pat(
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if ctx.completion.is_param == Some(ParamKind::Function) {
|
if matches!(
|
||||||
|
ctx.completion.pattern_ctx,
|
||||||
|
Some(PatternContext { is_param: Some(ParamKind::Function), .. })
|
||||||
|
) {
|
||||||
pat.push(':');
|
pat.push(':');
|
||||||
pat.push(' ');
|
pat.push(' ');
|
||||||
pat.push_str(name);
|
pat.push_str(name);
|
||||||
|
|
Loading…
Reference in a new issue