mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 20:43:21 +00:00
Complete repr
attribute parameters
This commit is contained in:
parent
84507a0b9c
commit
c1bf1f88ad
3 changed files with 202 additions and 2 deletions
|
@ -17,12 +17,14 @@ use crate::{
|
|||
|
||||
mod derive;
|
||||
mod lint;
|
||||
mod repr;
|
||||
|
||||
pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
|
||||
let attribute = ctx.attribute_under_caret.as_ref()?;
|
||||
match (attribute.path().and_then(|p| p.as_single_name_ref()), attribute.token_tree()) {
|
||||
(Some(path), Some(token_tree)) => match path.text().as_str() {
|
||||
"derive" => derive::complete_derive(acc, ctx, token_tree),
|
||||
"repr" => repr::complete_repr(acc, ctx, token_tree),
|
||||
"feature" => lint::complete_lint(acc, ctx, token_tree, FEATURES),
|
||||
"allow" | "warn" | "deny" | "forbid" => {
|
||||
lint::complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINTS);
|
||||
|
|
199
crates/ide_completion/src/completions/attribute/repr.rs
Normal file
199
crates/ide_completion/src/completions/attribute/repr.rs
Normal file
|
@ -0,0 +1,199 @@
|
|||
//! Completion for representations.
|
||||
|
||||
use syntax::ast;
|
||||
|
||||
use crate::{
|
||||
context::CompletionContext,
|
||||
item::{CompletionItem, CompletionItemKind, CompletionKind},
|
||||
Completions,
|
||||
};
|
||||
|
||||
pub(super) fn complete_repr(
|
||||
acc: &mut Completions,
|
||||
ctx: &CompletionContext,
|
||||
derive_input: ast::TokenTree,
|
||||
) {
|
||||
if let Some(existing_reprs) = super::parse_comma_sep_input(derive_input) {
|
||||
for repr_completion in REPR_COMPLETIONS {
|
||||
if existing_reprs
|
||||
.iter()
|
||||
.any(|it| repr_completion.label == it || repr_completion.collides.contains(&&**it))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let mut item = CompletionItem::new(
|
||||
CompletionKind::Attribute,
|
||||
ctx.source_range(),
|
||||
repr_completion.label,
|
||||
);
|
||||
item.kind(CompletionItemKind::Attribute);
|
||||
if let Some(lookup) = repr_completion.lookup {
|
||||
item.lookup_by(lookup);
|
||||
}
|
||||
if let Some((snippet, cap)) = repr_completion.snippet.zip(ctx.config.snippet_cap) {
|
||||
item.insert_snippet(cap, snippet);
|
||||
}
|
||||
item.add_to(acc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ReprCompletion {
|
||||
label: &'static str,
|
||||
snippet: Option<&'static str>,
|
||||
lookup: Option<&'static str>,
|
||||
collides: &'static [&'static str],
|
||||
}
|
||||
|
||||
const fn attr(label: &'static str, collides: &'static [&'static str]) -> ReprCompletion {
|
||||
ReprCompletion { label, snippet: None, lookup: None, collides }
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
const REPR_COMPLETIONS: &[ReprCompletion] = &[
|
||||
ReprCompletion { label: "align($0)", snippet: Some("align($0)"), lookup: Some("align"), collides: &["transparent", "packed"] },
|
||||
attr("packed", &["transparent", "align"]),
|
||||
attr("transparent", &["C", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
|
||||
attr("C", &["transparent"]),
|
||||
attr("u8", &["transparent", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
|
||||
attr("u16", &["transparent", "u8", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
|
||||
attr("u32", &["transparent", "u8", "u16", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
|
||||
attr("u64", &["transparent", "u8", "u16", "u32", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
|
||||
attr("u128", &["transparent", "u8", "u16", "u32", "u64", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
|
||||
attr("usize", &["transparent", "u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128", "isize"]),
|
||||
attr("i8", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i16", "i32", "i64", "i128", "isize"]),
|
||||
attr("i16", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i32", "i64", "i128", "isize"]),
|
||||
attr("i32", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i64", "i128", "isize"]),
|
||||
attr("i64", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i128", "isize"]),
|
||||
attr("i28", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "isize"]),
|
||||
attr("isize", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128"]),
|
||||
];
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use expect_test::{expect, Expect};
|
||||
|
||||
use crate::tests::completion_list;
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect) {
|
||||
let actual = completion_list(ra_fixture);
|
||||
expect.assert_eq(&actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_completion_for_incorrect_repr() {
|
||||
check(r#"#[repr{$0)] struct Test;"#, expect![[]])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
check(
|
||||
r#"#[repr($0)] struct Test;"#,
|
||||
expect![[r#"
|
||||
at align($0)
|
||||
at packed
|
||||
at transparent
|
||||
at C
|
||||
at u8
|
||||
at u16
|
||||
at u32
|
||||
at u64
|
||||
at u128
|
||||
at usize
|
||||
at i8
|
||||
at i16
|
||||
at i32
|
||||
at i64
|
||||
at i28
|
||||
at isize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transparent() {
|
||||
check(r#"#[repr(transparent, $0)] struct Test;"#, expect![[r#""#]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn align() {
|
||||
check(
|
||||
r#"#[repr(align(1), $0)] struct Test;"#,
|
||||
expect![[r#"
|
||||
at align($0)
|
||||
at transparent
|
||||
at C
|
||||
at u8
|
||||
at u16
|
||||
at u32
|
||||
at u64
|
||||
at u128
|
||||
at usize
|
||||
at i8
|
||||
at i16
|
||||
at i32
|
||||
at i64
|
||||
at i28
|
||||
at isize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn packed() {
|
||||
check(
|
||||
r#"#[repr(packed, $0)] struct Test;"#,
|
||||
expect![[r#"
|
||||
at transparent
|
||||
at C
|
||||
at u8
|
||||
at u16
|
||||
at u32
|
||||
at u64
|
||||
at u128
|
||||
at usize
|
||||
at i8
|
||||
at i16
|
||||
at i32
|
||||
at i64
|
||||
at i28
|
||||
at isize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn c() {
|
||||
check(
|
||||
r#"#[repr(C, $0)] struct Test;"#,
|
||||
expect![[r#"
|
||||
at align($0)
|
||||
at packed
|
||||
at u8
|
||||
at u16
|
||||
at u32
|
||||
at u64
|
||||
at u128
|
||||
at usize
|
||||
at i8
|
||||
at i16
|
||||
at i32
|
||||
at i64
|
||||
at i28
|
||||
at isize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prim() {
|
||||
check(
|
||||
r#"#[repr(usize, $0)] struct Test;"#,
|
||||
expect![[r#"
|
||||
at align($0)
|
||||
at packed
|
||||
at C
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -184,8 +184,7 @@ fn opt_self_param(p: &mut Parser, m: Marker) -> Result<(), Marker> {
|
|||
if !matches!(
|
||||
(p.current(), la1, la2, la3),
|
||||
(T![&], T![self], _, _)
|
||||
| (T![&], T![mut], T![self], _)
|
||||
| (T![&], LIFETIME_IDENT, T![self], _)
|
||||
| (T![&], T![mut] | LIFETIME_IDENT, T![self], _)
|
||||
| (T![&], LIFETIME_IDENT, T![mut], T![self])
|
||||
) {
|
||||
return Err(m);
|
||||
|
|
Loading…
Reference in a new issue