Skip to content

Internal: Only run completion functions if their corresponding context is active #12570

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions crates/ide-completion/src/completions/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use syntax::{

use crate::{
completions::module_or_attr,
context::{CompletionContext, IdentContext, PathCompletionCtx, PathKind, Qualified},
context::{CompletionContext, PathCompletionCtx, PathKind, Qualified},
item::CompletionItem,
Completions,
};
Expand All @@ -34,11 +34,9 @@ pub(crate) use self::derive::complete_derive;
pub(crate) fn complete_known_attribute_input(
acc: &mut Completions,
ctx: &CompletionContext,
fake_attribute_under_caret: &ast::Attr,
) -> Option<()> {
let attribute = match &ctx.ident_ctx {
IdentContext::UnexpandedAttrTT { fake_attribute_under_caret: Some(it) } => it,
_ => return None,
};
let attribute = fake_attribute_under_caret;
let name_ref = match attribute.path() {
Some(p) => Some(p.as_single_name_ref()?),
None => None,
Expand Down Expand Up @@ -71,27 +69,30 @@ pub(crate) fn complete_known_attribute_input(
Some(())
}

pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) {
let (qualified, is_inner, annotated_item_kind) = match ctx.path_context() {
Some(&PathCompletionCtx {
pub(crate) fn complete_attribute(
acc: &mut Completions,
ctx: &CompletionContext,
path_ctx: &PathCompletionCtx,
) {
let (qualified, is_inner, annotated_item_kind) = match path_ctx {
&PathCompletionCtx {
kind: PathKind::Attr { kind, annotated_item_kind },
ref qualified,
..
}) => (qualified, kind == AttrKind::Inner, annotated_item_kind),
} => (qualified, kind == AttrKind::Inner, annotated_item_kind),
_ => return,
};

match qualified {
Qualified::With { resolution, is_super_chain, .. } => {
Qualified::With {
resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))),
is_super_chain,
..
} => {
if *is_super_chain {
acc.add_keyword(ctx, "super::");
}

let module = match resolution {
Some(hir::PathResolution::Def(hir::ModuleDef::Module(it))) => it,
_ => return,
};

for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
if let Some(def) = module_or_attr(ctx.db, def) {
acc.add_resolution(ctx, name, def);
Expand All @@ -110,7 +111,7 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext)
});
acc.add_nameref_keywords_with_colon(ctx);
}
Qualified::Infer => {}
Qualified::Infer | Qualified::With { .. } => {}
}

let attributes = annotated_item_kind.and_then(|kind| {
Expand Down
27 changes: 15 additions & 12 deletions crates/ide-completion/src/completions/attribute/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,30 @@ use crate::{
Completions,
};

pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
let (qualified, existing_derives) = match ctx.path_context() {
Some(PathCompletionCtx {
kind: PathKind::Derive { existing_derives }, qualified, ..
}) => (qualified, existing_derives),
pub(crate) fn complete_derive(
acc: &mut Completions,
ctx: &CompletionContext,
path_ctx: &PathCompletionCtx,
) {
let (qualified, existing_derives) = match path_ctx {
PathCompletionCtx { kind: PathKind::Derive { existing_derives }, qualified, .. } => {
(qualified, existing_derives)
}
_ => return,
};

let core = ctx.famous_defs().core();

match qualified {
Qualified::With { resolution, is_super_chain, .. } => {
Qualified::With {
resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))),
is_super_chain,
..
} => {
if *is_super_chain {
acc.add_keyword(ctx, "super::");
}

let module = match resolution {
Some(hir::PathResolution::Def(hir::ModuleDef::Module(it))) => it,
_ => return,
};

for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
let add_def = match def {
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => {
Expand Down Expand Up @@ -101,7 +104,7 @@ pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
});
acc.add_nameref_keywords_with_colon(ctx);
}
Qualified::Infer => {}
Qualified::Infer | Qualified::With { .. } => {}
}
}

Expand Down
32 changes: 13 additions & 19 deletions crates/ide-completion/src/completions/dot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,16 @@ use ide_db::FxHashSet;

use crate::{
context::{
CompletionContext, DotAccess, DotAccessKind, NameRefContext, NameRefKind,
PathCompletionCtx, PathKind, Qualified,
CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind, Qualified,
},
CompletionItem, CompletionItemKind, Completions,
};

/// Complete dot accesses, i.e. fields or methods.
pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
let (dot_access, receiver_ty) = match ctx.nameref_ctx() {
Some(NameRefContext {
kind:
Some(NameRefKind::DotAccess(access @ DotAccess { receiver_ty: Some(receiver_ty), .. })),
..
}) => (access, &receiver_ty.original),
_ => return complete_undotted_self(acc, ctx),
pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext, dot_access: &DotAccess) {
let receiver_ty = match dot_access {
DotAccess { receiver_ty: Some(receiver_ty), .. } => &receiver_ty.original,
_ => return,
};

// Suggest .await syntax for types that implement Future trait
Expand All @@ -43,18 +38,17 @@ pub(crate) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
complete_methods(ctx, &receiver_ty, |func| acc.add_method(ctx, func, None, None));
}

fn complete_undotted_self(acc: &mut Completions, ctx: &CompletionContext) {
pub(crate) fn complete_undotted_self(
acc: &mut Completions,
ctx: &CompletionContext,
path_ctx: &PathCompletionCtx,
) {
if !ctx.config.enable_self_on_the_fly {
return;
}
match ctx.path_context() {
Some(
path_ctx @ PathCompletionCtx {
qualified: Qualified::No,
kind: PathKind::Expr { .. },
..
},
) if path_ctx.is_trivial_path() && ctx.qualifier_ctx.none() => {}
match path_ctx {
PathCompletionCtx { qualified: Qualified::No, kind: PathKind::Expr { .. }, .. }
if path_ctx.is_trivial_path() && ctx.qualifier_ctx.none() => {}
_ => return,
}

Expand Down
19 changes: 10 additions & 9 deletions crates/ide-completion/src/completions/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ use crate::{
CompletionContext, Completions,
};

pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext) {
pub(crate) fn complete_expr_path(
acc: &mut Completions,
ctx: &CompletionContext,
name_ref_ctx: &NameRefContext,
) {
let _p = profile::span("complete_expr_path");

let (
Expand All @@ -19,8 +23,8 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
after_if_expr,
wants_mut_token,
in_condition,
) = match ctx.nameref_ctx() {
Some(&NameRefContext {
) = match name_ref_ctx {
&NameRefContext {
kind:
Some(NameRefKind::Path(PathCompletionCtx {
kind:
Expand All @@ -36,7 +40,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
..
})),
..
}) if ctx.qualifier_ctx.none() => (
} if ctx.qualifier_ctx.none() => (
qualified,
in_block_expr,
in_loop_body,
Expand Down Expand Up @@ -65,11 +69,8 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
.into_iter()
.flat_map(|it| hir::Trait::from(it).items(ctx.sema.db))
.for_each(|item| add_assoc_item(acc, ctx, item)),
Qualified::With { resolution, .. } => {
let resolution = match resolution {
Some(it) => it,
None => return,
};
Qualified::With { resolution: None, .. } => {}
Qualified::With { resolution: Some(resolution), .. } => {
// Add associated types on type parameters and `Self`.
ctx.scope.assoc_type_shorthand_candidates(resolution, |_, alias| {
acc.add_type_alias(ctx, alias);
Expand Down
22 changes: 10 additions & 12 deletions crates/ide-completion/src/completions/extern_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ use syntax::{
};

use crate::{
completions::Completions,
context::{CompletionContext, IdentContext},
CompletionItem, CompletionItemKind,
completions::Completions, context::CompletionContext, CompletionItem, CompletionItemKind,
};

// Most of these are feature gated, we should filter/add feature gate completions once we have them.
Expand Down Expand Up @@ -42,15 +40,15 @@ const SUPPORTED_CALLING_CONVENTIONS: &[&str] = &[
"unadjusted",
];

pub(crate) fn complete_extern_abi(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
let abi_str = match &ctx.ident_ctx {
IdentContext::String { expanded: Some(expanded), .. }
if expanded.syntax().parent().map_or(false, |it| ast::Abi::can_cast(it.kind())) =>
{
expanded
}
_ => return None,
};
pub(crate) fn complete_extern_abi(
acc: &mut Completions,
_ctx: &CompletionContext,
expanded: &ast::String,
) -> Option<()> {
if !expanded.syntax().parent().map_or(false, |it| ast::Abi::can_cast(it.kind())) {
return None;
}
let abi_str = expanded;
let source_range = abi_str.text_range_between_quotes()?;
for &abi in SUPPORTED_CALLING_CONVENTIONS {
CompletionItem::new(CompletionItemKind::Keyword, source_range, abi).add_to(acc);
Expand Down
34 changes: 26 additions & 8 deletions crates/ide-completion/src/completions/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@

use crate::{
context::{
IdentContext, NameContext, NameKind, NameRefContext, NameRefKind, PathCompletionCtx,
PathKind, Qualified, TypeLocation,
NameContext, NameKind, NameRefContext, NameRefKind, PathCompletionCtx, PathKind, Qualified,
TypeLocation,
},
CompletionContext, Completions,
};

pub(crate) fn complete_field_list(acc: &mut Completions, ctx: &CompletionContext) {
match &ctx.ident_ctx {
IdentContext::Name(NameContext { kind: NameKind::RecordField, .. })
| IdentContext::NameRef(NameRefContext {
pub(crate) fn complete_field_list_tuple_variant(
acc: &mut Completions,
ctx: &CompletionContext,
name_ref_ctx: &NameRefContext,
) {
match name_ref_ctx {
NameRefContext {
kind:
Some(NameRefKind::Path(PathCompletionCtx {
has_macro_bang: false,
Expand All @@ -22,14 +25,29 @@ pub(crate) fn complete_field_list(acc: &mut Completions, ctx: &CompletionContext
..
})),
..
}) => {
} => {
if ctx.qualifier_ctx.vis_node.is_none() {
let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
add_keyword("pub(crate)", "pub(crate)");
add_keyword("pub(super)", "pub(super)");
add_keyword("pub", "pub");
}
}
_ => return,
_ => (),
}
}

pub(crate) fn complete_field_list_record_variant(
acc: &mut Completions,
ctx: &CompletionContext,
name_ctx: &NameContext,
) {
if let NameContext { kind: NameKind::RecordField, .. } = name_ctx {
if ctx.qualifier_ctx.vis_node.is_none() {
let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
add_keyword("pub(crate)", "pub(crate)");
add_keyword("pub(super)", "pub(super)");
add_keyword("pub", "pub");
}
}
}
10 changes: 7 additions & 3 deletions crates/ide-completion/src/completions/fn_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ use crate::{
/// `spam: &mut Spam` insert text/label will be suggested.
///
/// Also complete parameters for closure or local functions from the surrounding defined locals.
pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
let (param_list, _, param_kind) = match &ctx.pattern_ctx {
Some(PatternContext { param_ctx: Some(kind), .. }) => kind,
pub(crate) fn complete_fn_param(
acc: &mut Completions,
ctx: &CompletionContext,
pattern_ctx: &PatternContext,
) -> Option<()> {
let (param_list, _, param_kind) = match pattern_ctx {
PatternContext { param_ctx: Some(kind), .. } => kind,
_ => return None,
};

Expand Down
27 changes: 12 additions & 15 deletions crates/ide-completion/src/completions/format_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,25 @@

use ide_db::syntax_helpers::format_string::is_format_string;
use itertools::Itertools;
use syntax::{AstToken, TextRange, TextSize};
use syntax::{ast, AstToken, TextRange, TextSize};

use crate::{
context::{CompletionContext, IdentContext},
CompletionItem, CompletionItemKind, Completions,
};
use crate::{context::CompletionContext, CompletionItem, CompletionItemKind, Completions};

/// Complete identifiers in format strings.
pub(crate) fn format_string(acc: &mut Completions, ctx: &CompletionContext) {
let string = match &ctx.ident_ctx {
IdentContext::String { expanded: Some(expanded), original }
if is_format_string(&expanded) =>
{
original
}
_ => return,
};
pub(crate) fn format_string(
acc: &mut Completions,
ctx: &CompletionContext,
original: &ast::String,
expanded: &ast::String,
) {
if !is_format_string(&expanded) {
return;
}
let cursor = ctx.position.offset;
let lit_start = ctx.original_token.text_range().start();
let cursor_in_lit = cursor - lit_start;

let prefix = &string.text()[..cursor_in_lit.into()];
let prefix = &original.text()[..cursor_in_lit.into()];
let braces = prefix.char_indices().rev().skip_while(|&(_, c)| c.is_alphanumeric()).next_tuple();
let brace_offset = match braces {
// escaped brace
Expand Down
Loading