9899: minor: Simplify r=Veykril a=Veykril

bors r+

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-08-14 17:10:04 +00:00 committed by GitHub
commit 01de9021cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 58 deletions

View file

@ -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;
} }

View file

@ -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,
}; };

View file

@ -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 });
}
} }
} }

View file

@ -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)) => {

View file

@ -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);