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.
|
|
|
|
|
|
|
|
use ra_syntax::{
|
2020-05-04 15:07:51 +02:00
|
|
|
ast::{self, AttrInput, AttrKind},
|
2020-05-01 03:46:17 +03:00
|
|
|
AstNode, SyntaxKind,
|
2020-04-23 18:22:33 +02:00
|
|
|
};
|
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()) {
|
|
|
|
(Some(path), Some(AttrInput::TokenTree(token_tree))) if path.to_string() == "derive" => {
|
|
|
|
complete_derive(acc, ctx, token_tree)
|
|
|
|
}
|
|
|
|
_ => complete_attribute_start(acc, ctx, attribute),
|
|
|
|
}
|
|
|
|
Some(())
|
|
|
|
}
|
2020-04-23 18:22:33 +02:00
|
|
|
|
2020-05-01 03:46:17 +03: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);
|
|
|
|
|
|
|
|
match (attr_completion.snippet, ctx.config.snippet_cap) {
|
|
|
|
(Some(snippet), Some(cap)) => {
|
|
|
|
item = item.insert_snippet(cap, snippet);
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
|
2020-05-01 03:46:17 +03:00
|
|
|
if attribute.kind() == AttrKind::Inner || !attr_completion.should_be_inner {
|
2020-04-23 18:22:33 +02:00
|
|
|
acc.add(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct AttrCompletion {
|
|
|
|
label: &'static str,
|
|
|
|
snippet: Option<&'static str>,
|
|
|
|
should_be_inner: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
const ATTRIBUTES: &[AttrCompletion] = &[
|
|
|
|
AttrCompletion { label: "allow", snippet: Some("allow(${0:lint})"), should_be_inner: false },
|
|
|
|
AttrCompletion {
|
|
|
|
label: "cfg_attr",
|
|
|
|
snippet: Some("cfg_attr(${1:predicate}, ${0:attr})"),
|
|
|
|
should_be_inner: false,
|
|
|
|
},
|
|
|
|
AttrCompletion { label: "cfg", snippet: Some("cfg(${0:predicate})"), should_be_inner: false },
|
|
|
|
AttrCompletion { label: "deny", snippet: Some("deny(${0:lint})"), should_be_inner: false },
|
|
|
|
AttrCompletion {
|
|
|
|
label: "deprecated",
|
|
|
|
snippet: Some(r#"deprecated = "${0:reason}""#),
|
|
|
|
should_be_inner: false,
|
|
|
|
},
|
|
|
|
AttrCompletion {
|
|
|
|
label: "derive",
|
|
|
|
snippet: Some(r#"derive(${0:Debug})"#),
|
|
|
|
should_be_inner: false,
|
|
|
|
},
|
|
|
|
AttrCompletion { label: "doc", snippet: Some(r#"doc = "${0:docs}""#), should_be_inner: false },
|
|
|
|
AttrCompletion { label: "feature", snippet: Some("feature(${0:flag})"), should_be_inner: true },
|
|
|
|
AttrCompletion { label: "forbid", snippet: Some("forbid(${0:lint})"), should_be_inner: false },
|
|
|
|
// FIXME: resolve through macro resolution?
|
|
|
|
AttrCompletion { label: "global_allocator", snippet: None, should_be_inner: true },
|
|
|
|
AttrCompletion { label: "ignore", snippet: Some("ignore(${0:lint})"), should_be_inner: false },
|
|
|
|
AttrCompletion { label: "inline", snippet: Some("inline(${0:lint})"), should_be_inner: false },
|
|
|
|
AttrCompletion {
|
|
|
|
label: "link_name",
|
|
|
|
snippet: Some(r#"link_name = "${0:symbol_name}""#),
|
|
|
|
should_be_inner: false,
|
|
|
|
},
|
|
|
|
AttrCompletion { label: "link", snippet: None, should_be_inner: false },
|
|
|
|
AttrCompletion { label: "macro_export", snippet: None, should_be_inner: false },
|
|
|
|
AttrCompletion { label: "macro_use", snippet: None, should_be_inner: false },
|
|
|
|
AttrCompletion {
|
|
|
|
label: "must_use",
|
|
|
|
snippet: Some(r#"must_use = "${0:reason}""#),
|
|
|
|
should_be_inner: false,
|
|
|
|
},
|
|
|
|
AttrCompletion { label: "no_mangle", snippet: None, should_be_inner: false },
|
|
|
|
AttrCompletion { label: "no_std", snippet: None, should_be_inner: true },
|
|
|
|
AttrCompletion { label: "non_exhaustive", snippet: None, should_be_inner: false },
|
|
|
|
AttrCompletion { label: "panic_handler", snippet: None, should_be_inner: true },
|
|
|
|
AttrCompletion { label: "path", snippet: Some("path =\"${0:path}\""), should_be_inner: false },
|
|
|
|
AttrCompletion { label: "proc_macro", snippet: None, should_be_inner: false },
|
|
|
|
AttrCompletion { label: "proc_macro_attribute", snippet: None, should_be_inner: false },
|
|
|
|
AttrCompletion {
|
|
|
|
label: "proc_macro_derive",
|
|
|
|
snippet: Some("proc_macro_derive(${0:Trait})"),
|
|
|
|
should_be_inner: false,
|
|
|
|
},
|
|
|
|
AttrCompletion {
|
|
|
|
label: "recursion_limit",
|
|
|
|
snippet: Some("recursion_limit = ${0:128}"),
|
|
|
|
should_be_inner: true,
|
|
|
|
},
|
|
|
|
AttrCompletion { label: "repr", snippet: Some("repr(${0:C})"), should_be_inner: false },
|
|
|
|
AttrCompletion {
|
|
|
|
label: "should_panic",
|
|
|
|
snippet: Some(r#"expected = "${0:reason}""#),
|
|
|
|
should_be_inner: false,
|
|
|
|
},
|
|
|
|
AttrCompletion {
|
|
|
|
label: "target_feature",
|
|
|
|
snippet: Some("target_feature = \"${0:feature}\""),
|
|
|
|
should_be_inner: false,
|
|
|
|
},
|
|
|
|
AttrCompletion { label: "test", snippet: None, should_be_inner: false },
|
|
|
|
AttrCompletion { label: "used", snippet: None, should_be_inner: false },
|
|
|
|
AttrCompletion { label: "warn", snippet: Some("warn(${0:lint})"), should_be_inner: false },
|
|
|
|
AttrCompletion {
|
|
|
|
label: "windows_subsystem",
|
|
|
|
snippet: Some(r#"windows_subsystem = "${0:subsystem}""#),
|
|
|
|
should_be_inner: true,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
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",
|
|
|
|
source_range: 30..30,
|
|
|
|
delete: 30..30,
|
|
|
|
insert: "Clone",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Copy, Clone",
|
|
|
|
source_range: 30..30,
|
|
|
|
delete: 30..30,
|
|
|
|
insert: "Copy, Clone",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Debug",
|
|
|
|
source_range: 30..30,
|
|
|
|
delete: 30..30,
|
|
|
|
insert: "Debug",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Default",
|
|
|
|
source_range: 30..30,
|
|
|
|
delete: 30..30,
|
|
|
|
insert: "Default",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Eq, PartialEq",
|
|
|
|
source_range: 30..30,
|
|
|
|
delete: 30..30,
|
|
|
|
insert: "Eq, PartialEq",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Hash",
|
|
|
|
source_range: 30..30,
|
|
|
|
delete: 30..30,
|
|
|
|
insert: "Hash",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Ord, PartialOrd, Eq, PartialEq",
|
|
|
|
source_range: 30..30,
|
|
|
|
delete: 30..30,
|
|
|
|
insert: "Ord, PartialOrd, Eq, PartialEq",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "PartialEq",
|
|
|
|
source_range: 30..30,
|
|
|
|
delete: 30..30,
|
|
|
|
insert: "PartialEq",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "PartialOrd, PartialEq",
|
|
|
|
source_range: 30..30,
|
|
|
|
delete: 30..30,
|
|
|
|
insert: "PartialOrd, PartialEq",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
]
|
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[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-05-02 23:45:44 +03:00
|
|
|
source_range: 59..59,
|
|
|
|
delete: 59..59,
|
2020-05-01 03:46:17 +03:00
|
|
|
insert: "Clone",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Copy, Clone",
|
2020-05-02 23:45:44 +03:00
|
|
|
source_range: 59..59,
|
|
|
|
delete: 59..59,
|
2020-05-01 03:46:17 +03:00
|
|
|
insert: "Copy, Clone",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Debug",
|
2020-05-02 23:45:44 +03:00
|
|
|
source_range: 59..59,
|
|
|
|
delete: 59..59,
|
2020-05-01 03:46:17 +03:00
|
|
|
insert: "Debug",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Default",
|
2020-05-02 23:45:44 +03:00
|
|
|
source_range: 59..59,
|
|
|
|
delete: 59..59,
|
2020-05-01 03:46:17 +03:00
|
|
|
insert: "Default",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Eq",
|
2020-05-02 23:45:44 +03:00
|
|
|
source_range: 59..59,
|
|
|
|
delete: 59..59,
|
2020-05-01 03:46:17 +03:00
|
|
|
insert: "Eq",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Hash",
|
2020-05-02 23:45:44 +03:00
|
|
|
source_range: 59..59,
|
|
|
|
delete: 59..59,
|
2020-05-01 03:46:17 +03:00
|
|
|
insert: "Hash",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "Ord, PartialOrd, Eq",
|
2020-05-02 23:45:44 +03:00
|
|
|
source_range: 59..59,
|
|
|
|
delete: 59..59,
|
2020-05-01 03:46:17 +03:00
|
|
|
insert: "Ord, PartialOrd, Eq",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "PartialOrd",
|
2020-05-02 23:45:44 +03:00
|
|
|
source_range: 59..59,
|
|
|
|
delete: 59..59,
|
2020-05-01 03:46:17 +03:00
|
|
|
insert: "PartialOrd",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
]
|
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
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-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "allow(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "cfg",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "cfg(${0:predicate})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "cfg_attr",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "cfg_attr(${1:predicate}, ${0:attr})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "deny",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "deny(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "deprecated",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "deprecated = \"${0:reason}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "derive",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "derive(${0:Debug})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "doc",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "doc = \"${0:docs}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "forbid",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "forbid(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "ignore",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "ignore(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "inline",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "inline(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "link",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "link",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "link_name",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "link_name = \"${0:symbol_name}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "macro_export",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "macro_export",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "macro_use",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "macro_use",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "must_use",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "must_use = \"${0:reason}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "no_mangle",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "no_mangle",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "non_exhaustive",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "non_exhaustive",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "path",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "path =\"${0:path}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "proc_macro",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "proc_macro",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "proc_macro_attribute",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "proc_macro_attribute",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "proc_macro_derive",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "proc_macro_derive(${0:Trait})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "repr",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "repr(${0:C})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "should_panic",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "expected = \"${0:reason}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "target_feature",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "target_feature = \"${0:feature}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "test",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "test",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "used",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "used",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "warn",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 19..19,
|
|
|
|
delete: 19..19,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "warn(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
]
|
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_inner_attribute_completion() {
|
|
|
|
assert_debug_snapshot!(
|
|
|
|
do_attr_completion(
|
|
|
|
r"
|
|
|
|
#![<|>]
|
|
|
|
",
|
|
|
|
),
|
|
|
|
@r###"
|
|
|
|
[
|
|
|
|
CompletionItem {
|
|
|
|
label: "allow",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "allow(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "cfg",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "cfg(${0:predicate})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "cfg_attr",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "cfg_attr(${1:predicate}, ${0:attr})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "deny",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "deny(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "deprecated",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "deprecated = \"${0:reason}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "derive",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "derive(${0:Debug})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "doc",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "doc = \"${0:docs}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "feature",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "feature(${0:flag})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "forbid",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "forbid(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "global_allocator",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "global_allocator",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "ignore",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "ignore(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "inline",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "inline(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "link",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "link",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "link_name",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "link_name = \"${0:symbol_name}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "macro_export",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "macro_export",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "macro_use",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "macro_use",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "must_use",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "must_use = \"${0:reason}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "no_mangle",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "no_mangle",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "no_std",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "no_std",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "non_exhaustive",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "non_exhaustive",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "panic_handler",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "panic_handler",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "path",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "path =\"${0:path}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "proc_macro",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "proc_macro",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "proc_macro_attribute",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "proc_macro_attribute",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "proc_macro_derive",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "proc_macro_derive(${0:Trait})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "recursion_limit",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "recursion_limit = ${0:128}",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "repr",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "repr(${0:C})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "should_panic",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "expected = \"${0:reason}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "target_feature",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "target_feature = \"${0:feature}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "test",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "test",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "used",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "used",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "warn",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "warn(${0:lint})",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
CompletionItem {
|
|
|
|
label: "windows_subsystem",
|
2020-04-24 23:51:02 +02:00
|
|
|
source_range: 20..20,
|
|
|
|
delete: 20..20,
|
2020-04-23 18:22:33 +02:00
|
|
|
insert: "windows_subsystem = \"${0:subsystem}\"",
|
|
|
|
kind: Attribute,
|
|
|
|
},
|
|
|
|
]
|
|
|
|
"###
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|