rust/crates/ra_ide/src/completion/complete_attribute.rs

990 lines
31 KiB
Rust
Raw Normal View History

2020-04-23 18:22:33 +02:00
//! Completion for attributes
//!
//! This module uses a bit of static metadata to provide completions
//! for built-in attributes.
2020-05-04 15:08:51 +02:00
use ra_syntax::{ast, AstNode, SyntaxKind};
2020-05-01 03:46:17 +03:00
use rustc_hash::FxHashSet;
2020-04-23 18:22:33 +02:00
2020-05-04 15:07:51 +02:00
use crate::completion::{
completion_context::CompletionContext,
completion_item::{CompletionItem, CompletionItemKind, CompletionKind, Completions},
};
2020-05-01 03:46:17 +03:00
pub(super) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
let attribute = ctx.attribute_under_caret.as_ref()?;
2020-04-23 18:22:33 +02:00
2020-05-01 03:46:17 +03:00
match (attribute.path(), attribute.input()) {
2020-05-04 15:08:51 +02:00
(Some(path), Some(ast::AttrInput::TokenTree(token_tree)))
if path.to_string() == "derive" =>
{
2020-05-01 03:46:17 +03:00
complete_derive(acc, ctx, token_tree)
}
(_, Some(ast::AttrInput::TokenTree(_token_tree))) => {}
_ => complete_attribute_start(acc, ctx, attribute),
2020-05-01 03:46:17 +03:00
}
Some(())
}
2020-04-23 18:22:33 +02:00
fn complete_attribute_start(acc: &mut Completions, ctx: &CompletionContext, attribute: &ast::Attr) {
2020-04-23 18:22:33 +02:00
for attr_completion in ATTRIBUTES {
let mut item = CompletionItem::new(
CompletionKind::Attribute,
ctx.source_range(),
attr_completion.label,
)
.kind(CompletionItemKind::Attribute);
if let Some(lookup) = attr_completion.lookup {
item = item.lookup_by(lookup);
}
2020-04-23 18:22:33 +02:00
match (attr_completion.snippet, ctx.config.snippet_cap) {
(Some(snippet), Some(cap)) => {
item = item.insert_snippet(cap, snippet);
}
_ => {}
}
2020-05-04 15:08:51 +02:00
if attribute.kind() == ast::AttrKind::Inner || !attr_completion.should_be_inner {
acc.add(item);
2020-04-23 18:22:33 +02:00
}
}
}
struct AttrCompletion {
label: &'static str,
lookup: Option<&'static str>,
2020-04-23 18:22:33 +02:00
snippet: Option<&'static str>,
should_be_inner: bool,
}
const ATTRIBUTES: &[AttrCompletion] = &[
AttrCompletion {
label: "allow(…)",
snippet: Some("allow(${0:lint})"),
should_be_inner: false,
lookup: Some("allow"),
},
AttrCompletion {
label: "cfg_attr(…)",
2020-04-23 18:22:33 +02:00
snippet: Some("cfg_attr(${1:predicate}, ${0:attr})"),
should_be_inner: false,
lookup: Some("cfg_attr"),
2020-04-23 18:22:33 +02:00
},
AttrCompletion {
label: "cfg(…)",
snippet: Some("cfg(${0:predicate})"),
should_be_inner: false,
lookup: Some("cfg"),
},
AttrCompletion {
label: "deny(…)",
snippet: Some("deny(${0:lint})"),
should_be_inner: false,
lookup: Some("deny"),
},
AttrCompletion {
label: r#"deprecated = """#,
2020-04-23 18:22:33 +02:00
snippet: Some(r#"deprecated = "${0:reason}""#),
should_be_inner: false,
lookup: Some("deprecated"),
2020-04-23 18:22:33 +02:00
},
AttrCompletion {
label: "derive(…)",
2020-04-23 18:22:33 +02:00
snippet: Some(r#"derive(${0:Debug})"#),
should_be_inner: false,
lookup: Some("derive"),
2020-04-23 18:22:33 +02:00
},
AttrCompletion {
label: r#"doc = """#,
snippet: Some(r#"doc = "${0:docs}""#),
should_be_inner: false,
lookup: Some("doc"),
},
AttrCompletion {
label: "feature(…)",
snippet: Some("feature(${0:flag})"),
should_be_inner: true,
lookup: Some("feature"),
},
AttrCompletion {
label: "forbid(…)",
snippet: Some("forbid(${0:lint})"),
should_be_inner: false,
lookup: Some("forbid"),
},
2020-04-23 18:22:33 +02:00
// FIXME: resolve through macro resolution?
AttrCompletion {
label: "global_allocator",
snippet: None,
should_be_inner: true,
lookup: None,
},
2020-04-23 18:22:33 +02:00
AttrCompletion {
label: "ignore(…)",
snippet: Some("ignore(${0:lint})"),
should_be_inner: false,
lookup: Some("ignore"),
},
AttrCompletion {
label: "inline(…)",
snippet: Some("inline(${0:lint})"),
should_be_inner: false,
lookup: Some("inline"),
},
AttrCompletion {
label: r#"link_name = """#,
2020-04-23 18:22:33 +02:00
snippet: Some(r#"link_name = "${0:symbol_name}""#),
should_be_inner: false,
lookup: Some("link_name"),
2020-04-23 18:22:33 +02:00
},
AttrCompletion { label: "link", snippet: None, should_be_inner: false, lookup: None },
AttrCompletion { label: "macro_export", snippet: None, should_be_inner: false, lookup: None },
AttrCompletion { label: "macro_use", snippet: None, should_be_inner: false, lookup: None },
2020-04-23 18:22:33 +02:00
AttrCompletion {
label: r#"must_use = """#,
2020-04-23 18:22:33 +02:00
snippet: Some(r#"must_use = "${0:reason}""#),
should_be_inner: false,
lookup: Some("must_use"),
2020-04-23 18:22:33 +02:00
},
AttrCompletion { label: "no_mangle", snippet: None, should_be_inner: false, lookup: None },
AttrCompletion { label: "no_std", snippet: None, should_be_inner: true, lookup: None },
AttrCompletion { label: "non_exhaustive", snippet: None, should_be_inner: false, lookup: None },
AttrCompletion { label: "panic_handler", snippet: None, should_be_inner: true, lookup: None },
AttrCompletion {
label: "path = \"\"",
snippet: Some("path =\"${0:path}\""),
should_be_inner: false,
lookup: Some("path"),
},
AttrCompletion { label: "proc_macro", snippet: None, should_be_inner: false, lookup: None },
AttrCompletion {
label: "proc_macro_attribute",
snippet: None,
should_be_inner: false,
lookup: None,
},
2020-04-23 18:22:33 +02:00
AttrCompletion {
label: "proc_macro_derive(…)",
2020-04-23 18:22:33 +02:00
snippet: Some("proc_macro_derive(${0:Trait})"),
should_be_inner: false,
lookup: Some("proc_macro_derive"),
2020-04-23 18:22:33 +02:00
},
AttrCompletion {
label: "recursion_limit = …",
2020-04-23 18:22:33 +02:00
snippet: Some("recursion_limit = ${0:128}"),
should_be_inner: true,
lookup: Some("recursion_limit"),
},
AttrCompletion {
label: "repr(…)",
snippet: Some("repr(${0:C})"),
should_be_inner: false,
lookup: Some("repr"),
2020-04-23 18:22:33 +02:00
},
AttrCompletion {
label: "should_panic(…)",
snippet: Some(r#"should_panic(expected = "${0:reason}")"#),
2020-04-23 18:22:33 +02:00
should_be_inner: false,
lookup: Some("should_panic"),
2020-04-23 18:22:33 +02:00
},
AttrCompletion {
label: r#"target_feature = """#,
2020-04-23 18:22:33 +02:00
snippet: Some("target_feature = \"${0:feature}\""),
should_be_inner: false,
lookup: Some("target_feature"),
},
AttrCompletion { label: "test", snippet: None, should_be_inner: false, lookup: None },
AttrCompletion { label: "used", snippet: None, should_be_inner: false, lookup: None },
AttrCompletion {
label: "warn(…)",
snippet: Some("warn(${0:lint})"),
should_be_inner: false,
lookup: Some("warn"),
2020-04-23 18:22:33 +02:00
},
AttrCompletion {
label: r#"windows_subsystem = """#,
2020-04-23 18:22:33 +02:00
snippet: Some(r#"windows_subsystem = "${0:subsystem}""#),
should_be_inner: true,
lookup: Some("windows_subsystem"),
2020-04-23 18:22:33 +02:00
},
];
2020-05-01 03:46:17 +03:00
fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, derive_input: ast::TokenTree) {
if let Ok(existing_derives) = parse_derive_input(derive_input) {
2020-05-02 22:24:27 +03:00
for derive_completion in DEFAULT_DERIVE_COMPLETIONS
2020-05-01 03:46:17 +03:00
.into_iter()
.filter(|completion| !existing_derives.contains(completion.label))
{
let mut label = derive_completion.label.to_owned();
for dependency in derive_completion
.dependencies
.into_iter()
.filter(|&&dependency| !existing_derives.contains(dependency))
{
label.push_str(", ");
label.push_str(dependency);
}
2020-05-02 22:24:27 +03:00
acc.add(
CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label)
.kind(CompletionItemKind::Attribute),
);
}
for custom_derive_name in get_derive_names_in_scope(ctx).difference(&existing_derives) {
acc.add(
CompletionItem::new(
CompletionKind::Attribute,
ctx.source_range(),
custom_derive_name,
)
.kind(CompletionItemKind::Attribute),
);
2020-05-01 03:46:17 +03:00
}
}
}
fn parse_derive_input(derive_input: ast::TokenTree) -> Result<FxHashSet<String>, ()> {
match (derive_input.left_delimiter_token(), derive_input.right_delimiter_token()) {
(Some(left_paren), Some(right_paren))
if left_paren.kind() == SyntaxKind::L_PAREN
&& right_paren.kind() == SyntaxKind::R_PAREN =>
{
2020-05-02 23:45:44 +03:00
let mut input_derives = FxHashSet::default();
let mut current_derive = String::new();
for token in derive_input
2020-05-01 03:46:17 +03:00
.syntax()
.children_with_tokens()
2020-05-02 23:45:44 +03:00
.filter_map(|token| token.into_token())
.skip_while(|token| token != &left_paren)
.skip(1)
.take_while(|token| token != &right_paren)
{
if SyntaxKind::COMMA == token.kind() {
if !current_derive.is_empty() {
input_derives.insert(current_derive);
current_derive = String::new();
}
} else {
current_derive.push_str(token.to_string().trim());
}
}
if !current_derive.is_empty() {
input_derives.insert(current_derive);
}
Ok(input_derives)
2020-05-01 03:46:17 +03:00
}
_ => Err(()),
}
}
2020-05-02 22:24:27 +03:00
fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet<String> {
let mut result = FxHashSet::default();
ctx.scope().process_all_names(&mut |name, scope_def| {
if let hir::ScopeDef::MacroDef(mac) = scope_def {
if mac.is_derive_macro() {
2020-05-02 23:45:44 +03:00
result.insert(name.to_string());
2020-05-02 22:24:27 +03:00
}
}
});
result
}
2020-05-01 03:46:17 +03:00
struct DeriveCompletion {
label: &'static str,
dependencies: &'static [&'static str],
}
2020-05-02 22:24:27 +03:00
/// Standard Rust derives and the information about their dependencies
/// (the dependencies are needed so that the main derive don't break the compilation when added)
const DEFAULT_DERIVE_COMPLETIONS: &[DeriveCompletion] = &[
2020-05-01 03:46:17 +03:00
DeriveCompletion { label: "Clone", dependencies: &[] },
DeriveCompletion { label: "Copy", dependencies: &["Clone"] },
DeriveCompletion { label: "Debug", dependencies: &[] },
DeriveCompletion { label: "Default", dependencies: &[] },
DeriveCompletion { label: "Hash", dependencies: &[] },
DeriveCompletion { label: "PartialEq", dependencies: &[] },
DeriveCompletion { label: "Eq", dependencies: &["PartialEq"] },
DeriveCompletion { label: "PartialOrd", dependencies: &["PartialEq"] },
DeriveCompletion { label: "Ord", dependencies: &["PartialOrd", "Eq", "PartialEq"] },
];
2020-04-23 18:22:33 +02:00
#[cfg(test)]
mod tests {
use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
use insta::assert_debug_snapshot;
fn do_attr_completion(code: &str) -> Vec<CompletionItem> {
do_completion(code, CompletionKind::Attribute)
}
2020-05-01 03:46:17 +03:00
#[test]
fn empty_derive_completion() {
assert_debug_snapshot!(
do_attr_completion(
r"
#[derive(<|>)]
struct Test {}
",
),
@r###"
[
CompletionItem {
label: "Clone",
2020-06-24 11:29:43 +02:00
source_range: 9..9,
delete: 9..9,
2020-05-01 03:46:17 +03:00
insert: "Clone",
kind: Attribute,
},
CompletionItem {
label: "Copy, Clone",
2020-06-24 11:29:43 +02:00
source_range: 9..9,
delete: 9..9,
2020-05-01 03:46:17 +03:00
insert: "Copy, Clone",
kind: Attribute,
},
CompletionItem {
label: "Debug",
2020-06-24 11:29:43 +02:00
source_range: 9..9,
delete: 9..9,
2020-05-01 03:46:17 +03:00
insert: "Debug",
kind: Attribute,
},
CompletionItem {
label: "Default",
2020-06-24 11:29:43 +02:00
source_range: 9..9,
delete: 9..9,
2020-05-01 03:46:17 +03:00
insert: "Default",
kind: Attribute,
},
CompletionItem {
label: "Eq, PartialEq",
2020-06-24 11:29:43 +02:00
source_range: 9..9,
delete: 9..9,
2020-05-01 03:46:17 +03:00
insert: "Eq, PartialEq",
kind: Attribute,
},
CompletionItem {
label: "Hash",
2020-06-24 11:29:43 +02:00
source_range: 9..9,
delete: 9..9,
2020-05-01 03:46:17 +03:00
insert: "Hash",
kind: Attribute,
},
CompletionItem {
label: "Ord, PartialOrd, Eq, PartialEq",
2020-06-24 11:29:43 +02:00
source_range: 9..9,
delete: 9..9,
2020-05-01 03:46:17 +03:00
insert: "Ord, PartialOrd, Eq, PartialEq",
kind: Attribute,
},
CompletionItem {
label: "PartialEq",
2020-06-24 11:29:43 +02:00
source_range: 9..9,
delete: 9..9,
2020-05-01 03:46:17 +03:00
insert: "PartialEq",
kind: Attribute,
},
CompletionItem {
label: "PartialOrd, PartialEq",
2020-06-24 11:29:43 +02:00
source_range: 9..9,
delete: 9..9,
2020-05-01 03:46:17 +03:00
insert: "PartialOrd, PartialEq",
kind: Attribute,
},
]
2020-06-24 11:29:43 +02:00
"###
2020-05-01 03:46:17 +03:00
);
}
#[test]
fn no_completion_for_incorrect_derive() {
assert_debug_snapshot!(
do_attr_completion(
r"
#[derive{<|>)]
struct Test {}
",
),
@"[]"
);
}
#[test]
fn derive_with_input_completion() {
assert_debug_snapshot!(
do_attr_completion(
r"
2020-05-02 23:45:44 +03:00
#[derive(serde::Serialize, PartialEq, <|>)]
2020-05-01 03:46:17 +03:00
struct Test {}
",
),
@r###"
[
CompletionItem {
label: "Clone",
2020-06-24 11:29:43 +02:00
source_range: 38..38,
delete: 38..38,
2020-05-01 03:46:17 +03:00
insert: "Clone",
kind: Attribute,
},
CompletionItem {
label: "Copy, Clone",
2020-06-24 11:29:43 +02:00
source_range: 38..38,
delete: 38..38,
2020-05-01 03:46:17 +03:00
insert: "Copy, Clone",
kind: Attribute,
},
CompletionItem {
label: "Debug",
2020-06-24 11:29:43 +02:00
source_range: 38..38,
delete: 38..38,
2020-05-01 03:46:17 +03:00
insert: "Debug",
kind: Attribute,
},
CompletionItem {
label: "Default",
2020-06-24 11:29:43 +02:00
source_range: 38..38,
delete: 38..38,
2020-05-01 03:46:17 +03:00
insert: "Default",
kind: Attribute,
},
CompletionItem {
label: "Eq",
2020-06-24 11:29:43 +02:00
source_range: 38..38,
delete: 38..38,
2020-05-01 03:46:17 +03:00
insert: "Eq",
kind: Attribute,
},
CompletionItem {
label: "Hash",
2020-06-24 11:29:43 +02:00
source_range: 38..38,
delete: 38..38,
2020-05-01 03:46:17 +03:00
insert: "Hash",
kind: Attribute,
},
CompletionItem {
label: "Ord, PartialOrd, Eq",
2020-06-24 11:29:43 +02:00
source_range: 38..38,
delete: 38..38,
2020-05-01 03:46:17 +03:00
insert: "Ord, PartialOrd, Eq",
kind: Attribute,
},
CompletionItem {
label: "PartialOrd",
2020-06-24 11:29:43 +02:00
source_range: 38..38,
delete: 38..38,
2020-05-01 03:46:17 +03:00
insert: "PartialOrd",
kind: Attribute,
},
]
2020-06-24 11:29:43 +02:00
"###
2020-05-01 03:46:17 +03:00
);
}
2020-04-23 18:22:33 +02:00
#[test]
fn test_attribute_completion() {
assert_debug_snapshot!(
do_attr_completion(
r"
#[<|>]
",
),
@r###"
[
CompletionItem {
label: "allow(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "allow(${0:lint})",
kind: Attribute,
lookup: "allow",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "cfg(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "cfg(${0:predicate})",
kind: Attribute,
lookup: "cfg",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "cfg_attr(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "cfg_attr(${1:predicate}, ${0:attr})",
kind: Attribute,
lookup: "cfg_attr",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "deny(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "deny(${0:lint})",
kind: Attribute,
lookup: "deny",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "deprecated = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "deprecated = \"${0:reason}\"",
kind: Attribute,
lookup: "deprecated",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "derive(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "derive(${0:Debug})",
kind: Attribute,
lookup: "derive",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "doc = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "doc = \"${0:docs}\"",
kind: Attribute,
lookup: "doc",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "forbid(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "forbid(${0:lint})",
kind: Attribute,
lookup: "forbid",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "ignore(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "ignore(${0:lint})",
kind: Attribute,
lookup: "ignore",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "inline(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "inline(${0:lint})",
kind: Attribute,
lookup: "inline",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "link",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "link",
kind: Attribute,
},
CompletionItem {
label: "link_name = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "link_name = \"${0:symbol_name}\"",
kind: Attribute,
lookup: "link_name",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "macro_export",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "macro_export",
kind: Attribute,
},
CompletionItem {
label: "macro_use",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "macro_use",
kind: Attribute,
},
CompletionItem {
label: "must_use = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "must_use = \"${0:reason}\"",
kind: Attribute,
lookup: "must_use",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "no_mangle",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "no_mangle",
kind: Attribute,
},
CompletionItem {
label: "non_exhaustive",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "non_exhaustive",
kind: Attribute,
},
CompletionItem {
label: "path = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "path =\"${0:path}\"",
kind: Attribute,
lookup: "path",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "proc_macro",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "proc_macro",
kind: Attribute,
},
CompletionItem {
label: "proc_macro_attribute",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "proc_macro_attribute",
kind: Attribute,
},
CompletionItem {
label: "proc_macro_derive(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "proc_macro_derive(${0:Trait})",
kind: Attribute,
lookup: "proc_macro_derive",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "repr(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "repr(${0:C})",
kind: Attribute,
lookup: "repr",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "should_panic(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
insert: "should_panic(expected = \"${0:reason}\")",
2020-04-23 18:22:33 +02:00
kind: Attribute,
lookup: "should_panic",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "target_feature = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "target_feature = \"${0:feature}\"",
kind: Attribute,
lookup: "target_feature",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "test",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "test",
kind: Attribute,
},
CompletionItem {
label: "used",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "used",
kind: Attribute,
},
CompletionItem {
label: "warn(…)",
2020-06-24 11:29:43 +02:00
source_range: 2..2,
delete: 2..2,
2020-04-23 18:22:33 +02:00
insert: "warn(${0:lint})",
kind: Attribute,
lookup: "warn",
2020-04-23 18:22:33 +02:00
},
]
"###
);
}
#[test]
fn test_attribute_completion_inside_nested_attr() {
assert_debug_snapshot!(
do_attr_completion(
r"
#[allow(<|>)]
",
),
@r###"
[]
"###
);
}
2020-04-23 18:22:33 +02:00
#[test]
fn test_inner_attribute_completion() {
assert_debug_snapshot!(
do_attr_completion(
r"
#![<|>]
",
),
@r###"
[
CompletionItem {
label: "allow(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "allow(${0:lint})",
kind: Attribute,
lookup: "allow",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "cfg(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "cfg(${0:predicate})",
kind: Attribute,
lookup: "cfg",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "cfg_attr(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "cfg_attr(${1:predicate}, ${0:attr})",
kind: Attribute,
lookup: "cfg_attr",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "deny(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "deny(${0:lint})",
kind: Attribute,
lookup: "deny",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "deprecated = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "deprecated = \"${0:reason}\"",
kind: Attribute,
lookup: "deprecated",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "derive(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "derive(${0:Debug})",
kind: Attribute,
lookup: "derive",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "doc = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "doc = \"${0:docs}\"",
kind: Attribute,
lookup: "doc",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "feature(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "feature(${0:flag})",
kind: Attribute,
lookup: "feature",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "forbid(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "forbid(${0:lint})",
kind: Attribute,
lookup: "forbid",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "global_allocator",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "global_allocator",
kind: Attribute,
},
CompletionItem {
label: "ignore(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "ignore(${0:lint})",
kind: Attribute,
lookup: "ignore",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "inline(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "inline(${0:lint})",
kind: Attribute,
lookup: "inline",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "link",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "link",
kind: Attribute,
},
CompletionItem {
label: "link_name = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "link_name = \"${0:symbol_name}\"",
kind: Attribute,
lookup: "link_name",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "macro_export",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "macro_export",
kind: Attribute,
},
CompletionItem {
label: "macro_use",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "macro_use",
kind: Attribute,
},
CompletionItem {
label: "must_use = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "must_use = \"${0:reason}\"",
kind: Attribute,
lookup: "must_use",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "no_mangle",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "no_mangle",
kind: Attribute,
},
CompletionItem {
label: "no_std",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "no_std",
kind: Attribute,
},
CompletionItem {
label: "non_exhaustive",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "non_exhaustive",
kind: Attribute,
},
CompletionItem {
label: "panic_handler",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "panic_handler",
kind: Attribute,
},
CompletionItem {
label: "path = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "path =\"${0:path}\"",
kind: Attribute,
lookup: "path",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "proc_macro",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "proc_macro",
kind: Attribute,
},
CompletionItem {
label: "proc_macro_attribute",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "proc_macro_attribute",
kind: Attribute,
},
CompletionItem {
label: "proc_macro_derive(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "proc_macro_derive(${0:Trait})",
kind: Attribute,
lookup: "proc_macro_derive",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "recursion_limit = …",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "recursion_limit = ${0:128}",
kind: Attribute,
lookup: "recursion_limit",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "repr(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "repr(${0:C})",
kind: Attribute,
lookup: "repr",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "should_panic(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
insert: "should_panic(expected = \"${0:reason}\")",
2020-04-23 18:22:33 +02:00
kind: Attribute,
lookup: "should_panic",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "target_feature = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "target_feature = \"${0:feature}\"",
kind: Attribute,
lookup: "target_feature",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "test",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "test",
kind: Attribute,
},
CompletionItem {
label: "used",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "used",
kind: Attribute,
},
CompletionItem {
label: "warn(…)",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "warn(${0:lint})",
kind: Attribute,
lookup: "warn",
2020-04-23 18:22:33 +02:00
},
CompletionItem {
label: "windows_subsystem = \"\"",
2020-06-24 11:29:43 +02:00
source_range: 3..3,
delete: 3..3,
2020-04-23 18:22:33 +02:00
insert: "windows_subsystem = \"${0:subsystem}\"",
kind: Attribute,
lookup: "windows_subsystem",
2020-04-23 18:22:33 +02:00
},
]
"###
);
}
}