10558: internal: Refactor lifetime completion context fields r=Veykril a=Veykril

bors r+

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-10-16 21:57:36 +00:00 committed by GitHub
commit dd8e831c51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 43 deletions

View file

@ -10,23 +10,27 @@
use hir::ScopeDef; use hir::ScopeDef;
use syntax::ast; use syntax::ast;
use crate::{completions::Completions, context::CompletionContext}; use crate::{
completions::Completions,
context::{CompletionContext, LifetimeContext},
};
/// Completes lifetimes. /// Completes lifetimes.
pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext) { pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext) {
if !ctx.lifetime_allowed { let lp = match &ctx.lifetime_ctx {
return; Some(LifetimeContext::Lifetime) => None,
} Some(LifetimeContext::LifetimeParam(param)) => param.as_ref(),
_ => return,
};
let lp_string; let lp_string;
let param_lifetime = let param_lifetime = match (&ctx.name_syntax, lp.and_then(|lp| lp.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(ast::NameLike::Lifetime(lt)), Some(lp)) if lp == lt.clone() => return, (Some(_), Some(lp)) => {
(Some(_), Some(lp)) => { lp_string = lp.to_string();
lp_string = lp.to_string(); Some(&*lp_string)
Some(&*lp_string) }
} _ => None,
_ => None, };
};
ctx.scope.process_all_names(&mut |name, res| { ctx.scope.process_all_names(&mut |name, res| {
if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = 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. /// Completes labels.
pub(crate) fn complete_label(acc: &mut Completions, ctx: &CompletionContext) { pub(crate) fn complete_label(acc: &mut Completions, ctx: &CompletionContext) {
if !ctx.is_label_ref { if !matches!(ctx.lifetime_ctx, Some(LifetimeContext::LabelRef)) {
return; return;
} }
ctx.scope.process_all_names(&mut |name, res| { ctx.scope.process_all_names(&mut |name, res| {

View file

@ -60,6 +60,14 @@ pub(super) struct PatternContext {
pub(super) is_param: Option<ParamKind>, 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)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum CallKind { pub(crate) enum CallKind {
Pat, Pat,
@ -96,16 +104,12 @@ pub(crate) struct CompletionContext<'a> {
pub(super) impl_def: Option<ast::Impl>, pub(super) impl_def: Option<ast::Impl>,
pub(super) name_syntax: Option<ast::NameLike>, 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) 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) lifetime_ctx: Option<LifetimeContext>,
pub(super) pattern_ctx: Option<PatternContext>, pub(super) pattern_ctx: Option<PatternContext>,
pub(super) path_context: Option<PathCompletionContext>, pub(super) path_context: Option<PathCompletionContext>,
pub(super) locals: Vec<(String, Local)>, pub(super) locals: Vec<(String, Local)>,
@ -161,9 +165,7 @@ impl<'a> CompletionContext<'a> {
function_def: None, function_def: None,
impl_def: None, impl_def: None,
name_syntax: None, name_syntax: None,
lifetime_param_syntax: None, lifetime_ctx: None,
lifetime_allowed: false,
is_label_ref: false,
pattern_ctx: None, pattern_ctx: None,
completion_location: None, completion_location: None,
prev_sibling: None, prev_sibling: None,
@ -294,8 +296,14 @@ impl<'a> CompletionContext<'a> {
self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind) self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind)
} }
pub(crate) fn expects_assoc_item(&self) -> bool { pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> {
matches!(self.completion_location, Some(ImmediateLocation::Trait | ImmediateLocation::Impl)) match &self.completion_location {
Some(
ImmediateLocation::MethodCall { receiver, .. }
| ImmediateLocation::FieldAccess { receiver, .. },
) => receiver.as_ref(),
_ => None,
}
} }
pub(crate) fn has_dot_receiver(&self) -> bool { pub(crate) fn has_dot_receiver(&self) -> bool {
@ -306,14 +314,8 @@ impl<'a> CompletionContext<'a> {
) )
} }
pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> { pub(crate) fn expects_assoc_item(&self) -> bool {
match &self.completion_location { matches!(self.completion_location, Some(ImmediateLocation::Trait | ImmediateLocation::Impl))
Some(
ImmediateLocation::MethodCall { receiver, .. }
| ImmediateLocation::FieldAccess { receiver, .. },
) => receiver.as_ref(),
_ => None,
}
} }
pub(crate) fn expects_non_trait_assoc_item(&self) -> bool { pub(crate) fn expects_non_trait_assoc_item(&self) -> bool {
@ -676,19 +678,15 @@ impl<'a> CompletionContext<'a> {
return; return;
} }
match_ast! { self.lifetime_ctx = Some(match_ast! {
match parent { match parent {
ast::LifetimeParam(_it) => { ast::LifetimeParam(_it) => LifetimeContext::LifetimeParam(self.sema.find_node_at_offset_with_macros(original_file, offset)),
self.lifetime_allowed = true; ast::BreakExpr(_it) => LifetimeContext::LabelRef,
self.lifetime_param_syntax = ast::ContinueExpr(_it) => LifetimeContext::LabelRef,
self.sema.find_node_at_offset_with_macros(original_file, offset); ast::Label(_it) => LifetimeContext::LabelDef,
}, _ => LifetimeContext::Lifetime,
ast::BreakExpr(_it) => self.is_label_ref = true,
ast::ContinueExpr(_it) => self.is_label_ref = true,
ast::Label(_it) => (),
_ => self.lifetime_allowed = true,
} }
} });
} }
} }