Skip to content

Commit c9f0f47

Browse files
committed
simplify
1 parent 411eee7 commit c9f0f47

File tree

3 files changed

+92
-85
lines changed

3 files changed

+92
-85
lines changed

crates/ide_completion/src/completions/attribute.rs

Lines changed: 90 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
//! This module uses a bit of static metadata to provide completions
44
//! for built-in attributes.
55
6+
use std::mem;
7+
68
use once_cell::sync::Lazy;
79
use rustc_hash::{FxHashMap, FxHashSet};
8-
use syntax::{ast, AstNode, SyntaxKind, T};
10+
use syntax::{ast, AstNode, NodeOrToken, SyntaxKind, T};
911

1012
use crate::{
1113
context::CompletionContext,
@@ -105,82 +107,92 @@ const fn attr(
105107
}
106108

107109
macro_rules! attrs {
110+
// attributes applicable to all items
108111
[@ { item $($tt:tt)* } {$($acc:tt)*}] => {
109112
attrs!(@ { $($tt)* } { $($acc)*, "deprecated", "doc", "dochidden", "docalias", "must_use", "no_mangle" })
110113
};
114+
// attributes applicable to all adts
111115
[@ { adt $($tt:tt)* } {$($acc:tt)*}] => {
112116
attrs!(@ { $($tt)* } { $($acc)*, "derive", "repr" })
113117
};
118+
// attributes applicable to all linkable things aka functions/statics
114119
[@ { linkable $($tt:tt)* } {$($acc:tt)*}] => {
115-
attrs!(@ { $($tt)* } { $($acc)*, "export_name", "link_name", "link_section" }) };
116-
[@ { $ty:ident $($tt:tt)* } {$($acc:tt)*}] => { compile_error!(concat!("unknown attr subtype ", stringify!($ty)))
120+
attrs!(@ { $($tt)* } { $($acc)*, "export_name", "link_name", "link_section" })
121+
};
122+
// error fallback for nicer error message
123+
[@ { $ty:ident $($tt:tt)* } {$($acc:tt)*}] => {
124+
compile_error!(concat!("unknown attr subtype ", stringify!($ty)))
117125
};
126+
// general push down accumulation
118127
[@ { $lit:literal $($tt:tt)*} {$($acc:tt)*}] => {
119128
attrs!(@ { $($tt)* } { $($acc)*, $lit })
120129
};
121130
[@ {$($tt:tt)+} {$($tt2:tt)*}] => {
122131
compile_error!(concat!("Unexpected input ", stringify!($($tt)+)))
123132
};
133+
// final output construction
124134
[@ {} {$($tt:tt)*}] => { &[$($tt)*] as _ };
135+
// starting matcher
125136
[$($tt:tt),*] => {
126137
attrs!(@ { $($tt)* } { "allow", "cfg", "cfg_attr", "deny", "forbid", "warn" })
127138
};
128139
}
129140

130141
#[rustfmt::skip]
131142
static KIND_TO_ATTRIBUTES: Lazy<FxHashMap<SyntaxKind, &[&str]>> = Lazy::new(|| {
143+
use SyntaxKind::*;
132144
std::array::IntoIter::new([
133145
(
134-
SyntaxKind::SOURCE_FILE,
146+
SOURCE_FILE,
135147
attrs!(
136148
item,
137149
"crate_name", "feature", "no_implicit_prelude", "no_main", "no_std",
138150
"recursion_limit", "type_length_limit", "windows_subsystem"
139151
),
140152
),
141-
(SyntaxKind::MODULE, attrs!(item, "no_implicit_prelude", "path")),
142-
(SyntaxKind::ITEM_LIST, attrs!(item, "no_implicit_prelude")),
143-
(SyntaxKind::MACRO_RULES, attrs!(item, "macro_export", "macro_use")),
144-
(SyntaxKind::MACRO_DEF, attrs!(item)),
145-
(SyntaxKind::EXTERN_CRATE, attrs!(item, "macro_use", "no_link")),
146-
(SyntaxKind::USE, attrs!(item)),
147-
(SyntaxKind::TYPE_ALIAS, attrs!(item)),
148-
(SyntaxKind::STRUCT, attrs!(item, adt, "non_exhaustive")),
149-
(SyntaxKind::ENUM, attrs!(item, adt, "non_exhaustive")),
150-
(SyntaxKind::UNION, attrs!(item, adt)),
151-
(SyntaxKind::CONST, attrs!(item)),
153+
(MODULE, attrs!(item, "no_implicit_prelude", "path")),
154+
(ITEM_LIST, attrs!(item, "no_implicit_prelude")),
155+
(MACRO_RULES, attrs!(item, "macro_export", "macro_use")),
156+
(MACRO_DEF, attrs!(item)),
157+
(EXTERN_CRATE, attrs!(item, "macro_use", "no_link")),
158+
(USE, attrs!(item)),
159+
(TYPE_ALIAS, attrs!(item)),
160+
(STRUCT, attrs!(item, adt, "non_exhaustive")),
161+
(ENUM, attrs!(item, adt, "non_exhaustive")),
162+
(UNION, attrs!(item, adt)),
163+
(CONST, attrs!(item)),
152164
(
153-
SyntaxKind::FN,
165+
FN,
154166
attrs!(
155167
item, linkable,
156168
"cold", "ignore", "inline", "must_use", "panic_handler", "proc_macro",
157169
"proc_macro_derive", "proc_macro_attribute", "should_panic", "target_feature",
158170
"test", "track_caller"
159171
),
160172
),
161-
(SyntaxKind::STATIC, attrs!(item, linkable, "global_allocator", "used")),
162-
(SyntaxKind::TRAIT, attrs!(item, "must_use")),
163-
(SyntaxKind::IMPL, attrs!(item, "automatically_derived")),
164-
(SyntaxKind::ASSOC_ITEM_LIST, attrs!(item)),
165-
(SyntaxKind::EXTERN_BLOCK, attrs!(item, "link")),
166-
(SyntaxKind::EXTERN_ITEM_LIST, attrs!(item, "link")),
167-
(SyntaxKind::MACRO_CALL, attrs!()),
168-
(SyntaxKind::SELF_PARAM, attrs!()),
169-
(SyntaxKind::PARAM, attrs!()),
170-
(SyntaxKind::RECORD_FIELD, attrs!()),
171-
(SyntaxKind::VARIANT, attrs!("non_exhaustive")),
172-
(SyntaxKind::TYPE_PARAM, attrs!()),
173-
(SyntaxKind::CONST_PARAM, attrs!()),
174-
(SyntaxKind::LIFETIME_PARAM, attrs!()),
175-
(SyntaxKind::LET_STMT, attrs!()),
176-
(SyntaxKind::EXPR_STMT, attrs!()),
177-
(SyntaxKind::LITERAL, attrs!()),
178-
(SyntaxKind::RECORD_EXPR_FIELD_LIST, attrs!()),
179-
(SyntaxKind::RECORD_EXPR_FIELD, attrs!()),
180-
(SyntaxKind::MATCH_ARM_LIST, attrs!()),
181-
(SyntaxKind::MATCH_ARM, attrs!()),
182-
(SyntaxKind::IDENT_PAT, attrs!()),
183-
(SyntaxKind::RECORD_PAT_FIELD, attrs!()),
173+
(STATIC, attrs!(item, linkable, "global_allocator", "used")),
174+
(TRAIT, attrs!(item, "must_use")),
175+
(IMPL, attrs!(item, "automatically_derived")),
176+
(ASSOC_ITEM_LIST, attrs!(item)),
177+
(EXTERN_BLOCK, attrs!(item, "link")),
178+
(EXTERN_ITEM_LIST, attrs!(item, "link")),
179+
(MACRO_CALL, attrs!()),
180+
(SELF_PARAM, attrs!()),
181+
(PARAM, attrs!()),
182+
(RECORD_FIELD, attrs!()),
183+
(VARIANT, attrs!("non_exhaustive")),
184+
(TYPE_PARAM, attrs!()),
185+
(CONST_PARAM, attrs!()),
186+
(LIFETIME_PARAM, attrs!()),
187+
(LET_STMT, attrs!()),
188+
(EXPR_STMT, attrs!()),
189+
(LITERAL, attrs!()),
190+
(RECORD_EXPR_FIELD_LIST, attrs!()),
191+
(RECORD_EXPR_FIELD, attrs!()),
192+
(MATCH_ARM_LIST, attrs!()),
193+
(MATCH_ARM, attrs!()),
194+
(IDENT_PAT, attrs!()),
195+
(RECORD_PAT_FIELD, attrs!()),
184196
])
185197
.collect()
186198
});
@@ -257,62 +269,57 @@ const ATTRIBUTES: &[AttrCompletion] = &[
257269
.prefer_inner(),
258270
];
259271

260-
#[test]
261-
fn attributes_are_sorted() {
262-
let mut attrs = ATTRIBUTES.iter().map(|attr| attr.key());
263-
let mut prev = attrs.next().unwrap();
264-
265-
attrs.for_each(|next| {
266-
assert!(
267-
prev < next,
268-
r#"Attributes are not sorted, "{}" should come after "{}""#,
269-
prev,
270-
next
271-
);
272-
prev = next;
273-
});
274-
}
275-
276-
fn parse_comma_sep_input(derive_input: ast::TokenTree) -> Result<FxHashSet<String>, ()> {
277-
match (derive_input.left_delimiter_token(), derive_input.right_delimiter_token()) {
278-
(Some(left_paren), Some(right_paren))
279-
if left_paren.kind() == T!['('] && right_paren.kind() == T![')'] =>
280-
{
281-
let mut input_derives = FxHashSet::default();
282-
let mut current_derive = String::new();
283-
for token in derive_input
284-
.syntax()
285-
.children_with_tokens()
286-
.filter_map(|token| token.into_token())
287-
.skip_while(|token| token != &left_paren)
288-
.skip(1)
289-
.take_while(|token| token != &right_paren)
290-
{
291-
if T![,] == token.kind() {
292-
if !current_derive.is_empty() {
293-
input_derives.insert(current_derive);
294-
current_derive = String::new();
295-
}
296-
} else {
297-
current_derive.push_str(token.text().trim());
298-
}
299-
}
300-
272+
fn parse_comma_sep_input(derive_input: ast::TokenTree) -> Option<FxHashSet<String>> {
273+
let (l_paren, r_paren) = derive_input.l_paren_token().zip(derive_input.r_paren_token())?;
274+
let mut input_derives = FxHashSet::default();
275+
let mut current_derive = String::new();
276+
for token in derive_input
277+
.syntax()
278+
.children_with_tokens()
279+
.filter_map(NodeOrToken::into_token)
280+
.skip_while(|token| token != &l_paren)
281+
.skip(1)
282+
.take_while(|token| token != &r_paren)
283+
{
284+
if token.kind() == T![,] {
301285
if !current_derive.is_empty() {
302-
input_derives.insert(current_derive);
286+
input_derives.insert(mem::take(&mut current_derive));
303287
}
304-
Ok(input_derives)
288+
} else {
289+
current_derive.push_str(token.text().trim());
305290
}
306-
_ => Err(()),
307291
}
292+
293+
if !current_derive.is_empty() {
294+
input_derives.insert(current_derive);
295+
}
296+
Some(input_derives)
308297
}
309298

310299
#[cfg(test)]
311300
mod tests {
301+
use super::*;
302+
312303
use expect_test::{expect, Expect};
313304

314305
use crate::{test_utils::completion_list, CompletionKind};
315306

307+
#[test]
308+
fn attributes_are_sorted() {
309+
let mut attrs = ATTRIBUTES.iter().map(|attr| attr.key());
310+
let mut prev = attrs.next().unwrap();
311+
312+
attrs.for_each(|next| {
313+
assert!(
314+
prev < next,
315+
r#"ATTRIBUTES array is not sorted, "{}" should come after "{}""#,
316+
prev,
317+
next
318+
);
319+
prev = next;
320+
});
321+
}
322+
316323
fn check(ra_fixture: &str, expect: Expect) {
317324
let actual = completion_list(ra_fixture, CompletionKind::Attribute);
318325
expect.assert_eq(&actual);

crates/ide_completion/src/completions/attribute/derive.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub(super) fn complete_derive(
1414
ctx: &CompletionContext,
1515
derive_input: ast::TokenTree,
1616
) {
17-
if let Ok(existing_derives) = super::parse_comma_sep_input(derive_input) {
17+
if let Some(existing_derives) = super::parse_comma_sep_input(derive_input) {
1818
for derive_completion in DEFAULT_DERIVE_COMPLETIONS
1919
.iter()
2020
.filter(|completion| !existing_derives.contains(completion.label))

crates/ide_completion/src/completions/attribute/lint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub(super) fn complete_lint(
1313
derive_input: ast::TokenTree,
1414
lints_completions: &[LintCompletion],
1515
) {
16-
if let Ok(existing_lints) = super::parse_comma_sep_input(derive_input) {
16+
if let Some(existing_lints) = super::parse_comma_sep_input(derive_input) {
1717
for lint_completion in lints_completions
1818
.into_iter()
1919
.filter(|completion| !existing_lints.contains(completion.label))

0 commit comments

Comments
 (0)