Fix visibility mods not being completed for field defs

This commit is contained in:
Lukas Wirth 2022-06-03 15:41:51 +02:00
parent 519ac81b57
commit c5dcc77b40
10 changed files with 85 additions and 15 deletions

View File

@ -4,6 +4,7 @@ pub(crate) mod attribute;
pub(crate) mod dot;
pub(crate) mod expr;
pub(crate) mod extern_abi;
pub(crate) mod field;
pub(crate) mod flyimport;
pub(crate) mod fn_param;
pub(crate) mod format_string;

View File

@ -0,0 +1,53 @@
//! Completion of field list position.
use crate::{
context::{IdentContext, NameContext, NameKind, NameRefContext, PathCompletionCtx, PathKind},
CompletionContext, CompletionItem, CompletionItemKind, 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 {
path_ctx:
Some(PathCompletionCtx {
has_macro_bang: false,
is_absolute_path: false,
qualifier: None,
parent: None,
kind: PathKind::Type { in_tuple_struct: true },
has_type_args: false,
..
}),
..
}) => {
if ctx.qualifier_ctx.vis_node.is_none() {
let mut add_keyword = |kw, snippet| add_keyword(acc, ctx, kw, snippet);
add_keyword("pub(crate)", "pub(crate)");
add_keyword("pub(super)", "pub(super)");
add_keyword("pub", "pub");
}
}
_ => return,
}
}
pub(super) fn add_keyword(acc: &mut Completions, ctx: &CompletionContext, kw: &str, snippet: &str) {
let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw);
match ctx.config.snippet_cap {
Some(cap) => {
if snippet.ends_with('}') && ctx.incomplete_let {
// complete block expression snippets with a trailing semicolon, if inside an incomplete let
cov_mark::hit!(let_semi);
item.insert_snippet(cap, format!("{};", snippet));
} else {
item.insert_snippet(cap, snippet);
}
}
None => {
item.insert_text(if snippet.contains('$') { kw } else { snippet });
}
};
item.add_to(acc);
}

View File

@ -160,7 +160,10 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
(_, ItemInNs::Types(hir::ModuleDef::Module(_))) => true,
// and so are macros(except for attributes)
(
PathKind::Expr { .. } | PathKind::Type | PathKind::Item { .. } | PathKind::Pat,
PathKind::Expr { .. }
| PathKind::Type { .. }
| PathKind::Item { .. }
| PathKind::Pat,
ItemInNs::Macros(mac),
) => mac.is_fn_like(ctx.db),
(PathKind::Item { .. }, _) => true,
@ -170,14 +173,14 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
(PathKind::Pat, ItemInNs::Types(_)) => true,
(PathKind::Pat, ItemInNs::Values(def)) => matches!(def, hir::ModuleDef::Const(_)),
(PathKind::Type, ItemInNs::Types(ty)) => {
(PathKind::Type { .. }, ItemInNs::Types(ty)) => {
if matches!(ctx.completion_location, Some(ImmediateLocation::TypeBound)) {
matches!(ty, ModuleDef::Trait(_))
} else {
true
}
}
(PathKind::Type, ItemInNs::Values(_)) => false,
(PathKind::Type { .. }, ItemInNs::Values(_)) => false,
(PathKind::Attr { .. }, ItemInNs::Macros(mac)) => mac.is_attr(ctx.db),
(PathKind::Attr { .. }, _) => false,

View File

@ -18,9 +18,12 @@ pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext)
}
let (&is_absolute_path, qualifier) = match ctx.path_context() {
Some(PathCompletionCtx { kind: PathKind::Type, is_absolute_path, qualifier, .. }) => {
(is_absolute_path, qualifier)
}
Some(PathCompletionCtx {
kind: PathKind::Type { .. },
is_absolute_path,
qualifier,
..
}) => (is_absolute_path, qualifier),
_ => return,
};

View File

@ -49,7 +49,9 @@ pub(super) enum PathKind {
in_block_expr: bool,
in_loop_body: bool,
},
Type,
Type {
in_tuple_struct: bool,
},
Attr {
kind: AttrKind,
annotated_item_kind: Option<SyntaxKind>,
@ -1222,7 +1224,9 @@ impl<'a> CompletionContext<'a> {
// using Option<Option<PathKind>> as extra controlflow
let kind = match_ast! {
match it {
ast::PathType(_) => Some(PathKind::Type),
ast::PathType(it) => Some(PathKind::Type {
in_tuple_struct: it.syntax().parent().map_or(false, |it| ast::TupleField::can_cast(it.kind()))
}),
ast::PathExpr(it) => {
if let Some(p) = it.syntax().parent() {
if ast::ExprStmt::can_cast(p.kind()) {
@ -1262,7 +1266,7 @@ impl<'a> CompletionContext<'a> {
let parent = it.syntax().parent();
match parent.as_ref().map(|it| it.kind()) {
Some(SyntaxKind::MACRO_PAT) => Some(PathKind::Pat),
Some(SyntaxKind::MACRO_TYPE) => Some(PathKind::Type),
Some(SyntaxKind::MACRO_TYPE) => Some(PathKind::Type { in_tuple_struct: false }),
Some(SyntaxKind::ITEM_LIST) => Some(PathKind::Item { kind: ItemListKind::Module }),
Some(SyntaxKind::ASSOC_ITEM_LIST) => Some(PathKind::Item { kind: match parent.and_then(|it| it.parent()) {
Some(it) => match_ast! {

View File

@ -158,6 +158,7 @@ pub fn completions(
completions::dot::complete_dot(acc, ctx);
completions::expr::complete_expr_path(acc, ctx);
completions::extern_abi::complete_extern_abi(acc, ctx);
completions::field::complete_field_list(acc, ctx);
completions::flyimport::import_on_the_fly(acc, ctx);
completions::fn_param::complete_fn_param(acc, ctx);
completions::format_string::format_string(acc, ctx);

View File

@ -286,7 +286,7 @@ fn render_resolution_simple_(
// Add `<>` for generic types
let type_path_no_ty_args = matches!(
ctx.completion.path_context(),
Some(PathCompletionCtx { kind: PathKind::Type, has_type_args: false, .. })
Some(PathCompletionCtx { kind: PathKind::Type { .. }, has_type_args: false, .. })
) && ctx.completion.config.callable.is_some();
if type_path_no_ty_args {
if let Some(cap) = ctx.snippet_cap() {

View File

@ -202,7 +202,7 @@ fn should_add_parens(ctx: &CompletionContext) -> bool {
Some(PathCompletionCtx { kind: PathKind::Expr { .. }, has_call_parens: true, .. }) => {
return false
}
Some(PathCompletionCtx { kind: PathKind::Use | PathKind::Type, .. }) => {
Some(PathCompletionCtx { kind: PathKind::Use | PathKind::Type { .. }, .. }) => {
cov_mark::hit!(no_parens_in_use_item);
return false;
}

View File

@ -100,7 +100,6 @@ fn after_fn_name() {
#[test]
fn before_record_field() {
// FIXME: This should emit visibility qualifiers
check(
r#"
struct Foo {
@ -108,6 +107,10 @@ struct Foo {
pub f: i32,
}
"#,
expect![[r#""#]],
expect![[r#"
kw pub
kw pub(crate)
kw pub(super)
"#]],
)
}

View File

@ -38,14 +38,13 @@ struct Foo<'lt, T, const C: usize> {
#[test]
fn tuple_struct_field() {
// FIXME: This should emit visibility qualifiers
check(
r#"
struct Foo<'lt, T, const C: usize>(f$0);
"#,
expect![[r#"
en Enum
ma makro!() macro_rules! makro
ma makro!() macro_rules! makro
md module
sp Self
st Foo<>
@ -57,6 +56,9 @@ struct Foo<'lt, T, const C: usize>(f$0);
un Union
bt u32
kw crate::
kw pub
kw pub(crate)
kw pub(super)
kw self::
kw super::
"#]],