Skip to content

Commit

Permalink
Auto merge of rust-lang#12461 - Veykril:completions, r=Veykril
Browse files Browse the repository at this point in the history
Move trait_impl completion analysis into CompletionContext
  • Loading branch information
bors committed Jun 3, 2022
2 parents d06d0f8 + a2a74bf commit 312913a
Show file tree
Hide file tree
Showing 14 changed files with 403 additions and 437 deletions.
1 change: 0 additions & 1 deletion crates/ide-completion/src/completions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ pub(crate) mod pattern;
pub(crate) mod postfix;
pub(crate) mod record;
pub(crate) mod snippet;
pub(crate) mod trait_impl;
pub(crate) mod r#type;
pub(crate) mod use_;
pub(crate) mod vis;
Expand Down
14 changes: 8 additions & 6 deletions crates/ide-completion/src/completions/dot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ fn complete_undotted_self(acc: &mut Completions, ctx: &CompletionContext) {
return;
}
match ctx.path_context() {
Some(PathCompletionCtx {
is_absolute_path: false,
qualifier: None,
kind: PathKind::Expr { .. },
..
}) if !ctx.is_path_disallowed() => {}
Some(
path_ctx @ PathCompletionCtx {
is_absolute_path: false,
qualifier: None,
kind: PathKind::Expr { .. },
..
},
) if path_ctx.is_trivial_path() && ctx.qualifier_ctx.none() => {}
_ => return,
}

Expand Down
121 changes: 78 additions & 43 deletions crates/ide-completion/src/completions/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,38 @@ use crate::{

pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext) {
let _p = profile::span("complete_expr_path");
if ctx.is_path_disallowed() {
return;
}

let (is_absolute_path, qualifier, in_block_expr, in_loop_body, is_func_update, after_if_expr) =
match ctx.nameref_ctx() {
Some(NameRefContext {
path_ctx:
Some(PathCompletionCtx {
kind: PathKind::Expr { in_block_expr, in_loop_body, after_if_expr },
is_absolute_path,
qualifier,
..
}),
record_expr,
..
}) => (
*is_absolute_path,
qualifier,
*in_block_expr,
*in_loop_body,
record_expr.as_ref().map_or(false, |&(_, it)| it),
*after_if_expr,
),
_ => return,
};
let (
is_absolute_path,
qualifier,
in_block_expr,
in_loop_body,
is_func_update,
after_if_expr,
wants_mut_token,
) = match ctx.nameref_ctx() {
Some(NameRefContext {
path_ctx:
Some(PathCompletionCtx {
kind:
PathKind::Expr { in_block_expr, in_loop_body, after_if_expr, ref_expr_parent },
is_absolute_path,
qualifier,
..
}),
record_expr,
..
}) if ctx.qualifier_ctx.none() => (
*is_absolute_path,
qualifier,
*in_block_expr,
*in_loop_body,
record_expr.as_ref().map_or(false, |&(_, it)| it),
*after_if_expr,
ref_expr_parent.as_ref().map(|it| it.mut_token().is_none()).unwrap_or(false),
),
_ => return,
};

let scope_def_applicable = |def| {
use hir::{GenericParam::*, ModuleDef::*};
Expand Down Expand Up @@ -164,12 +170,43 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
None if is_absolute_path => acc.add_crate_roots(ctx),
None => {
acc.add_nameref_keywords_with_colon(ctx);
if let Some(hir::Adt::Enum(e)) =
if let Some(adt) =
ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
{
super::enum_variants_with_paths(acc, ctx, e, |acc, ctx, variant, path| {
acc.add_qualified_enum_variant(ctx, variant, path)
});
let self_ty =
(|| ctx.sema.to_def(ctx.impl_def.as_ref()?)?.self_ty(ctx.db).as_adt())();
let complete_self = self_ty == Some(adt);

match adt {
hir::Adt::Struct(strukt) => {
let path = ctx
.module
.find_use_path(ctx.db, hir::ModuleDef::from(strukt))
.filter(|it| it.len() > 1);

acc.add_struct_literal(ctx, strukt, path, None);

if complete_self {
acc.add_struct_literal(ctx, strukt, None, Some(hir::known::SELF_TYPE));
}
}
hir::Adt::Union(un) => {
let path = ctx
.module
.find_use_path(ctx.db, hir::ModuleDef::from(un))
.filter(|it| it.len() > 1);

acc.add_union_literal(ctx, un, path, None);
if complete_self {
acc.add_union_literal(ctx, un, None, Some(hir::known::SELF_TYPE));
}
}
hir::Adt::Enum(e) => {
super::enum_variants_with_paths(acc, ctx, e, |acc, ctx, variant, path| {
acc.add_qualified_enum_variant(ctx, variant, path)
});
}
}
}
ctx.process_all_names(&mut |name, def| {
if scope_def_applicable(def) {
Expand All @@ -180,20 +217,18 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
if !is_func_update {
let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);

if ctx.expects_expression() {
if !in_block_expr {
add_keyword("unsafe", "unsafe {\n $0\n}");
}
add_keyword("match", "match $1 {\n $0\n}");
add_keyword("while", "while $1 {\n $0\n}");
add_keyword("while let", "while let $1 = $2 {\n $0\n}");
add_keyword("loop", "loop {\n $0\n}");
add_keyword("if", "if $1 {\n $0\n}");
add_keyword("if let", "if let $1 = $2 {\n $0\n}");
add_keyword("for", "for $1 in $2 {\n $0\n}");
add_keyword("true", "true");
add_keyword("false", "false");
if !in_block_expr {
add_keyword("unsafe", "unsafe {\n $0\n}");
}
add_keyword("match", "match $1 {\n $0\n}");
add_keyword("while", "while $1 {\n $0\n}");
add_keyword("while let", "while let $1 = $2 {\n $0\n}");
add_keyword("loop", "loop {\n $0\n}");
add_keyword("if", "if $1 {\n $0\n}");
add_keyword("if let", "if let $1 = $2 {\n $0\n}");
add_keyword("for", "for $1 in $2 {\n $0\n}");
add_keyword("true", "true");
add_keyword("false", "false");

if ctx.previous_token_is(T![if])
|| ctx.previous_token_is(T![while])
Expand All @@ -207,7 +242,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
add_keyword("else if", "else if $1 {\n $0\n}");
}

if ctx.expects_ident_ref_expr() {
if wants_mut_token {
add_keyword("mut", "mut ");
}

Expand Down
44 changes: 23 additions & 21 deletions crates/ide-completion/src/completions/flyimport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use itertools::Itertools;
use syntax::{AstNode, SyntaxNode, T};

use crate::{
context::{CompletionContext, PathKind},
context::{CompletionContext, NameRefContext, PathCompletionCtx, PathKind, PatternContext},
patterns::ImmediateLocation,
render::{render_resolution_with_import, RenderContext},
};
Expand Down Expand Up @@ -110,16 +110,26 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
if !ctx.config.enable_imports_on_the_fly {
return None;
}
if matches!(ctx.path_kind(), Some(PathKind::Vis { .. } | PathKind::Use | PathKind::Item { .. }))
|| ctx.is_path_disallowed()
{
return None;
}
// FIXME: This should be encoded in a different way
if ctx.pattern_ctx.is_none() && ctx.path_context().is_none() && !ctx.has_dot_receiver() {
// completion inside `ast::Name` of a item declaration
return None;
}
let path_kind = match ctx.nameref_ctx() {
Some(NameRefContext { path_ctx: Some(PathCompletionCtx { kind, .. }), .. })
if matches!(
kind,
PathKind::Expr { .. }
| PathKind::Type { .. }
| PathKind::Attr { .. }
| PathKind::Derive
| PathKind::Pat
) =>
{
Some(kind)
}
Some(NameRefContext { dot_access: Some(_), .. }) => None,
None if matches!(ctx.pattern_ctx, Some(PatternContext { record_pat: None, .. })) => {
Some(&PathKind::Pat)
}
_ => return None,
};

let potential_import_name = {
let token_kind = ctx.token.kind();
if matches!(token_kind, T![.] | T![::]) {
Expand All @@ -138,18 +148,10 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
return None;
}

let path_kind = match ctx.path_kind() {
Some(kind) => Some(kind),
None if ctx.pattern_ctx.is_some() => Some(PathKind::Pat),
None => None,
};
let ns_filter = |import: &LocatedImport| {
let path_kind = match path_kind {
Some(path_kind) => path_kind,
None => match import.original_item {
ItemInNs::Macros(mac) => return mac.is_fn_like(ctx.db),
_ => return true,
},
Some(it) => it,
None => return true,
};
match (path_kind, import.original_item) {
// Aren't handled in flyimport
Expand Down
Loading

0 comments on commit 312913a

Please sign in to comment.