Unnamed repository; edit this file 'description' to name the repository.
Merge #10558
10558: internal: Refactor lifetime completion context fields r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <[email protected]>
bors[bot] 2021-10-17
parent 2d7d7f7 · parent 81ccebf · commit dd8e831
-rw-r--r--crates/ide_completion/src/completions/lifetime.rs32
-rw-r--r--crates/ide_completion/src/context.rs56
2 files changed, 45 insertions, 43 deletions
diff --git a/crates/ide_completion/src/completions/lifetime.rs b/crates/ide_completion/src/completions/lifetime.rs
index 233bf51ec0..283dc021d6 100644
--- a/crates/ide_completion/src/completions/lifetime.rs
+++ b/crates/ide_completion/src/completions/lifetime.rs
@@ -10,23 +10,27 @@
use hir::ScopeDef;
use syntax::ast;
-use crate::{completions::Completions, context::CompletionContext};
+use crate::{
+ completions::Completions,
+ context::{CompletionContext, LifetimeContext},
+};
/// Completes lifetimes.
pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext) {
- if !ctx.lifetime_allowed {
- return;
- }
+ let lp = match &ctx.lifetime_ctx {
+ Some(LifetimeContext::Lifetime) => None,
+ Some(LifetimeContext::LifetimeParam(param)) => param.as_ref(),
+ _ => return,
+ };
let lp_string;
- let param_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(_), Some(lp)) => {
- lp_string = lp.to_string();
- Some(&*lp_string)
- }
- _ => None,
- };
+ let param_lifetime = match (&ctx.name_syntax, lp.and_then(|lp| lp.lifetime())) {
+ (Some(ast::NameLike::Lifetime(lt)), Some(lp)) if lp == lt.clone() => return,
+ (Some(_), Some(lp)) => {
+ lp_string = lp.to_string();
+ Some(&*lp_string)
+ }
+ _ => None,
+ };
ctx.scope.process_all_names(&mut |name, 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.
pub(crate) fn complete_label(acc: &mut Completions, ctx: &CompletionContext) {
- if !ctx.is_label_ref {
+ if !matches!(ctx.lifetime_ctx, Some(LifetimeContext::LabelRef)) {
return;
}
ctx.scope.process_all_names(&mut |name, res| {
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index b75277f628..25da46f1d7 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -60,6 +60,14 @@ pub(super) struct PatternContext {
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)]
pub(crate) enum CallKind {
Pat,
@@ -96,16 +104,12 @@ pub(crate) struct CompletionContext<'a> {
pub(super) impl_def: Option<ast::Impl>,
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) prev_sibling: Option<ImmediatePrevSibling>,
pub(super) attribute_under_caret: Option<ast::Attr>,
pub(super) previous_token: Option<SyntaxToken>,
+ pub(super) lifetime_ctx: Option<LifetimeContext>,
pub(super) pattern_ctx: Option<PatternContext>,
pub(super) path_context: Option<PathCompletionContext>,
pub(super) locals: Vec<(String, Local)>,
@@ -161,9 +165,7 @@ impl<'a> CompletionContext<'a> {
function_def: None,
impl_def: None,
name_syntax: None,
- lifetime_param_syntax: None,
- lifetime_allowed: false,
- is_label_ref: false,
+ lifetime_ctx: None,
pattern_ctx: None,
completion_location: None,
prev_sibling: None,
@@ -294,8 +296,14 @@ impl<'a> CompletionContext<'a> {
self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind)
}
- pub(crate) fn expects_assoc_item(&self) -> bool {
- matches!(self.completion_location, Some(ImmediateLocation::Trait | ImmediateLocation::Impl))
+ pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> {
+ match &self.completion_location {
+ Some(
+ ImmediateLocation::MethodCall { receiver, .. }
+ | ImmediateLocation::FieldAccess { receiver, .. },
+ ) => receiver.as_ref(),
+ _ => None,
+ }
}
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> {
- match &self.completion_location {
- Some(
- ImmediateLocation::MethodCall { receiver, .. }
- | ImmediateLocation::FieldAccess { receiver, .. },
- ) => receiver.as_ref(),
- _ => None,
- }
+ pub(crate) fn expects_assoc_item(&self) -> bool {
+ matches!(self.completion_location, Some(ImmediateLocation::Trait | ImmediateLocation::Impl))
}
pub(crate) fn expects_non_trait_assoc_item(&self) -> bool {
@@ -676,19 +678,15 @@ impl<'a> CompletionContext<'a> {
return;
}
- match_ast! {
+ self.lifetime_ctx = Some(match_ast! {
match parent {
- ast::LifetimeParam(_it) => {
- self.lifetime_allowed = true;
- self.lifetime_param_syntax =
- self.sema.find_node_at_offset_with_macros(original_file, offset);
- },
- ast::BreakExpr(_it) => self.is_label_ref = true,
- ast::ContinueExpr(_it) => self.is_label_ref = true,
- ast::Label(_it) => (),
- _ => self.lifetime_allowed = true,
+ ast::LifetimeParam(_it) => LifetimeContext::LifetimeParam(self.sema.find_node_at_offset_with_macros(original_file, offset)),
+ ast::BreakExpr(_it) => LifetimeContext::LabelRef,
+ ast::ContinueExpr(_it) => LifetimeContext::LabelRef,
+ ast::Label(_it) => LifetimeContext::LabelDef,
+ _ => LifetimeContext::Lifetime,
}
- }
+ });
}
}