refactor complete_fn_fields function and correct branch checks
This commit is contained in:
parent
8296b16f38
commit
5c0c8ceaf7
2 changed files with 22 additions and 45 deletions
|
|
@ -26,23 +26,19 @@ pub(crate) fn complete_dot(
|
|||
item.add_to(acc, ctx.db);
|
||||
}
|
||||
|
||||
let is_field_access = matches!(dot_access.kind, DotAccessKind::Field { .. });
|
||||
|
||||
complete_fields(
|
||||
acc,
|
||||
ctx,
|
||||
receiver_ty,
|
||||
|acc, field, ty| acc.add_field(ctx, dot_access, None, field, &ty),
|
||||
|acc, field, ty| acc.add_tuple_field(ctx, None, field, &ty),
|
||||
is_field_access,
|
||||
);
|
||||
|
||||
if let DotAccessKind::Method { .. } = dot_access.kind {
|
||||
cov_mark::hit!(test_no_struct_field_completion_for_method_call);
|
||||
complete_fn_fields(
|
||||
acc,
|
||||
ctx,
|
||||
receiver_ty,
|
||||
|acc, field, ty| acc.add_field(ctx, dot_access, None, field, &ty),
|
||||
|acc, field, ty| acc.add_tuple_field(ctx, None, field, &ty),
|
||||
);
|
||||
} else {
|
||||
complete_fields(
|
||||
acc,
|
||||
ctx,
|
||||
receiver_ty,
|
||||
|acc, field, ty| acc.add_field(ctx, dot_access, None, field, &ty),
|
||||
|acc, field, ty| acc.add_tuple_field(ctx, None, field, &ty),
|
||||
);
|
||||
}
|
||||
complete_methods(ctx, receiver_ty, |func| acc.add_method(ctx, dot_access, func, None, None));
|
||||
}
|
||||
|
|
@ -89,6 +85,7 @@ pub(crate) fn complete_undotted_self(
|
|||
)
|
||||
},
|
||||
|acc, field, ty| acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), field, &ty),
|
||||
true,
|
||||
);
|
||||
complete_methods(ctx, &ty, |func| {
|
||||
acc.add_method(
|
||||
|
|
@ -111,18 +108,23 @@ fn complete_fields(
|
|||
receiver: &hir::Type,
|
||||
mut named_field: impl FnMut(&mut Completions, hir::Field, hir::Type),
|
||||
mut tuple_index: impl FnMut(&mut Completions, usize, hir::Type),
|
||||
is_field_access: bool,
|
||||
) {
|
||||
let mut seen_names = FxHashSet::default();
|
||||
for receiver in receiver.autoderef(ctx.db) {
|
||||
for (field, ty) in receiver.fields(ctx.db) {
|
||||
if seen_names.insert(field.name(ctx.db)) {
|
||||
if seen_names.insert(field.name(ctx.db))
|
||||
&& (is_field_access || ty.is_fn() || ty.is_closure())
|
||||
{
|
||||
named_field(acc, field, ty);
|
||||
}
|
||||
}
|
||||
for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() {
|
||||
// Tuples are always the last type in a deref chain, so just check if the name is
|
||||
// already seen without inserting into the hashset.
|
||||
if !seen_names.contains(&hir::Name::new_tuple_field(i)) {
|
||||
if !seen_names.contains(&hir::Name::new_tuple_field(i))
|
||||
&& (is_field_access || ty.is_fn() || ty.is_closure())
|
||||
{
|
||||
// Tuple fields are always public (tuple struct fields are handled above).
|
||||
tuple_index(acc, i, ty);
|
||||
}
|
||||
|
|
@ -151,33 +153,6 @@ fn complete_methods(
|
|||
);
|
||||
}
|
||||
|
||||
fn complete_fn_fields(
|
||||
acc: &mut Completions,
|
||||
ctx: &CompletionContext<'_>,
|
||||
receiver: &hir::Type,
|
||||
mut named_field: impl FnMut(&mut Completions, hir::Field, hir::Type),
|
||||
mut tuple_index: impl FnMut(&mut Completions, usize, hir::Type),
|
||||
) {
|
||||
let mut seen_names = FxHashSet::default();
|
||||
for receiver in receiver.autoderef(ctx.db) {
|
||||
for (field, ty) in receiver.fields(ctx.db) {
|
||||
if seen_names.insert(field.name(ctx.db)) && (ty.is_fn() || ty.is_closure()) {
|
||||
named_field(acc, field, ty);
|
||||
}
|
||||
}
|
||||
for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() {
|
||||
// Tuples are always the last type in a deref chain, so just check if the name is
|
||||
// already seen without inserting into the hashset.
|
||||
if !seen_names.contains(&hir::Name::new_tuple_field(i))
|
||||
&& (ty.is_fn() || ty.is_closure())
|
||||
{
|
||||
// Tuple fields are always public (tuple struct fields are handled above).
|
||||
tuple_index(acc, i, ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use expect_test::{expect, Expect};
|
||||
|
|
|
|||
|
|
@ -148,7 +148,9 @@ pub(crate) fn render_field(
|
|||
.set_documentation(field.docs(db))
|
||||
.set_deprecated(is_deprecated)
|
||||
.lookup_by(name);
|
||||
if ty.is_fn() || ty.is_closure() {
|
||||
|
||||
let is_field_access = matches!(dot_access.kind, DotAccessKind::Field { .. });
|
||||
if !is_field_access || ty.is_fn() || ty.is_closure() {
|
||||
let mut builder = TextEdit::builder();
|
||||
// Using TextEdit, insert '(' before the struct name and ')' before the
|
||||
// dot access, then comes the field name and optionally insert function
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue