mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 13:18:47 +00:00
Complete pub
in fields
This commit is contained in:
parent
6b8bc132dc
commit
18b667cfcb
7 changed files with 76 additions and 8 deletions
|
@ -129,8 +129,9 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
|
|||
add_keyword(ctx, acc, "break", "break");
|
||||
}
|
||||
}
|
||||
if ctx.has_item_list_or_source_file_parent || ctx.has_impl_parent {
|
||||
add_keyword(ctx, acc, "pub", "pub ")
|
||||
if ctx.has_item_list_or_source_file_parent || ctx.has_impl_parent | ctx.has_field_list_parent {
|
||||
add_keyword(ctx, acc, "pub(crate)", "pub(crate) ");
|
||||
add_keyword(ctx, acc, "pub", "pub ");
|
||||
}
|
||||
|
||||
if !ctx.is_trivial_path {
|
||||
|
@ -227,6 +228,7 @@ mod tests {
|
|||
kw impl
|
||||
kw mod
|
||||
kw pub
|
||||
kw pub(crate)
|
||||
kw static
|
||||
kw struct
|
||||
kw trait
|
||||
|
@ -364,6 +366,7 @@ fn quux() -> i32 {
|
|||
kw const
|
||||
kw fn
|
||||
kw pub
|
||||
kw pub(crate)
|
||||
kw type
|
||||
kw unsafe
|
||||
"#]],
|
||||
|
@ -524,4 +527,20 @@ pub mod future {
|
|||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn before_field() {
|
||||
check(
|
||||
r#"
|
||||
struct Foo {
|
||||
<|>
|
||||
pub f: i32,
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
kw pub
|
||||
kw pub(crate)
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,6 @@ fn ${1:feature}() {
|
|||
.add_to(acc);
|
||||
|
||||
snippet(ctx, cap, "macro_rules", "macro_rules! $1 {\n\t($2) => {\n\t\t$0\n\t};\n}").add_to(acc);
|
||||
snippet(ctx, cap, "pub(crate)", "pub(crate) $0").add_to(acc);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -107,7 +106,6 @@ mod tests {
|
|||
"#,
|
||||
expect![[r#"
|
||||
sn macro_rules
|
||||
sn pub(crate)
|
||||
sn tfn (Test function)
|
||||
sn tmod (Test module)
|
||||
"#]],
|
||||
|
|
|
@ -16,9 +16,10 @@ use crate::{
|
|||
call_info::ActiveParameter,
|
||||
completion::{
|
||||
patterns::{
|
||||
has_bind_pat_parent, has_block_expr_parent, has_impl_as_prev_sibling, has_impl_parent,
|
||||
has_item_list_or_source_file_parent, has_ref_parent, has_trait_as_prev_sibling,
|
||||
has_trait_parent, if_is_prev, is_in_loop_body, is_match_arm, unsafe_is_prev,
|
||||
has_bind_pat_parent, has_block_expr_parent, has_field_list_parent,
|
||||
has_impl_as_prev_sibling, has_impl_parent, has_item_list_or_source_file_parent,
|
||||
has_ref_parent, has_trait_as_prev_sibling, has_trait_parent, if_is_prev,
|
||||
is_in_loop_body, is_match_arm, unsafe_is_prev,
|
||||
},
|
||||
CompletionConfig,
|
||||
},
|
||||
|
@ -84,6 +85,7 @@ pub(crate) struct CompletionContext<'a> {
|
|||
pub(super) in_loop_body: bool,
|
||||
pub(super) has_trait_parent: bool,
|
||||
pub(super) has_impl_parent: bool,
|
||||
pub(super) has_field_list_parent: bool,
|
||||
pub(super) trait_as_prev_sibling: bool,
|
||||
pub(super) impl_as_prev_sibling: bool,
|
||||
pub(super) is_match_arm: bool,
|
||||
|
@ -157,6 +159,7 @@ impl<'a> CompletionContext<'a> {
|
|||
block_expr_parent: false,
|
||||
has_trait_parent: false,
|
||||
has_impl_parent: false,
|
||||
has_field_list_parent: false,
|
||||
trait_as_prev_sibling: false,
|
||||
impl_as_prev_sibling: false,
|
||||
if_is_prev: false,
|
||||
|
@ -230,6 +233,7 @@ impl<'a> CompletionContext<'a> {
|
|||
self.in_loop_body = is_in_loop_body(syntax_element.clone());
|
||||
self.has_trait_parent = has_trait_parent(syntax_element.clone());
|
||||
self.has_impl_parent = has_impl_parent(syntax_element.clone());
|
||||
self.has_field_list_parent = has_field_list_parent(syntax_element.clone());
|
||||
self.impl_as_prev_sibling = has_impl_as_prev_sibling(syntax_element.clone());
|
||||
self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone());
|
||||
self.is_match_arm = is_match_arm(syntax_element.clone());
|
||||
|
|
|
@ -34,6 +34,14 @@ pub(crate) fn has_impl_parent(element: SyntaxElement) -> bool {
|
|||
fn test_has_impl_parent() {
|
||||
check_pattern_is_applicable(r"impl A { f<|> }", has_impl_parent);
|
||||
}
|
||||
pub(crate) fn has_field_list_parent(element: SyntaxElement) -> bool {
|
||||
not_same_range_ancestor(element).filter(|it| it.kind() == RECORD_FIELD_LIST).is_some()
|
||||
}
|
||||
#[test]
|
||||
fn test_has_field_list_parent() {
|
||||
check_pattern_is_applicable(r"struct Foo { f<|> }", has_field_list_parent);
|
||||
check_pattern_is_applicable(r"struct Foo { f<|> pub f: i32}", has_field_list_parent);
|
||||
}
|
||||
|
||||
pub(crate) fn has_block_expr_parent(element: SyntaxElement) -> bool {
|
||||
not_same_range_ancestor(element).filter(|it| it.kind() == BLOCK_EXPR).is_some()
|
||||
|
|
|
@ -18,7 +18,14 @@ pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(token_set![
|
|||
T![dyn],
|
||||
]);
|
||||
|
||||
const TYPE_RECOVERY_SET: TokenSet = token_set![R_PAREN, COMMA, L_DOLLAR];
|
||||
const TYPE_RECOVERY_SET: TokenSet = token_set![
|
||||
T![')'],
|
||||
T![,],
|
||||
L_DOLLAR,
|
||||
// test_err struct_field_recover
|
||||
// struct S { f pub g: () }
|
||||
T![pub],
|
||||
];
|
||||
|
||||
pub(crate) fn type_(p: &mut Parser) {
|
||||
type_with_bounds_cond(p, true);
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
SOURCE_FILE@0..25
|
||||
STRUCT@0..24
|
||||
STRUCT_KW@0..6 "struct"
|
||||
WHITESPACE@6..7 " "
|
||||
NAME@7..8
|
||||
IDENT@7..8 "S"
|
||||
WHITESPACE@8..9 " "
|
||||
RECORD_FIELD_LIST@9..24
|
||||
L_CURLY@9..10 "{"
|
||||
WHITESPACE@10..11 " "
|
||||
RECORD_FIELD@11..12
|
||||
NAME@11..12
|
||||
IDENT@11..12 "f"
|
||||
WHITESPACE@12..13 " "
|
||||
RECORD_FIELD@13..22
|
||||
VISIBILITY@13..16
|
||||
PUB_KW@13..16 "pub"
|
||||
WHITESPACE@16..17 " "
|
||||
NAME@17..18
|
||||
IDENT@17..18 "g"
|
||||
COLON@18..19 ":"
|
||||
WHITESPACE@19..20 " "
|
||||
TUPLE_TYPE@20..22
|
||||
L_PAREN@20..21 "("
|
||||
R_PAREN@21..22 ")"
|
||||
WHITESPACE@22..23 " "
|
||||
R_CURLY@23..24 "}"
|
||||
WHITESPACE@24..25 "\n"
|
||||
error 12..12: expected COLON
|
||||
error 12..12: expected type
|
||||
error 12..12: expected COMMA
|
|
@ -0,0 +1 @@
|
|||
struct S { f pub g: () }
|
Loading…
Reference in a new issue