diff options
Diffstat (limited to 'crates/ide_completion/src')
-rw-r--r-- | crates/ide_completion/src/completions/attribute.rs | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs index 76d926157..c48bb9e66 100644 --- a/crates/ide_completion/src/completions/attribute.rs +++ b/crates/ide_completion/src/completions/attribute.rs | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | use once_cell::sync::Lazy; | 6 | use once_cell::sync::Lazy; |
7 | use rustc_hash::{FxHashMap, FxHashSet}; | 7 | use rustc_hash::{FxHashMap, FxHashSet}; |
8 | use syntax::{ast, AstNode, NodeOrToken, SyntaxKind, T}; | 8 | use syntax::{algo::non_trivia_sibling, ast, AstNode, Direction, NodeOrToken, SyntaxKind, T}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | context::CompletionContext, | 11 | context::CompletionContext, |
@@ -37,7 +37,13 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) | |||
37 | } | 37 | } |
38 | 38 | ||
39 | fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attribute: &ast::Attr) { | 39 | fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attribute: &ast::Attr) { |
40 | let attribute_annotated_item_kind = attribute.syntax().parent().map(|it| it.kind()); | 40 | let is_inner = attribute.kind() == ast::AttrKind::Inner; |
41 | let attribute_annotated_item_kind = | ||
42 | attribute.syntax().parent().map(|it| it.kind()).filter(|_| { | ||
43 | is_inner | ||
44 | // If we got nothing coming after the attribute it could be anything so filter it the kind out | ||
45 | || non_trivia_sibling(attribute.syntax().clone().into(), Direction::Next).is_some() | ||
46 | }); | ||
41 | let attributes = attribute_annotated_item_kind.and_then(|kind| { | 47 | let attributes = attribute_annotated_item_kind.and_then(|kind| { |
42 | if ast::Expr::can_cast(kind) { | 48 | if ast::Expr::can_cast(kind) { |
43 | Some(EXPR_ATTRIBUTES) | 49 | Some(EXPR_ATTRIBUTES) |
@@ -45,7 +51,6 @@ fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attrib | |||
45 | KIND_TO_ATTRIBUTES.get(&kind).copied() | 51 | KIND_TO_ATTRIBUTES.get(&kind).copied() |
46 | } | 52 | } |
47 | }); | 53 | }); |
48 | let is_inner = attribute.kind() == ast::AttrKind::Inner; | ||
49 | 54 | ||
50 | let add_completion = |attr_completion: &AttrCompletion| { | 55 | let add_completion = |attr_completion: &AttrCompletion| { |
51 | let mut item = CompletionItem::new( | 56 | let mut item = CompletionItem::new( |
@@ -781,4 +786,49 @@ mod tests { | |||
781 | "#]], | 786 | "#]], |
782 | ); | 787 | ); |
783 | } | 788 | } |
789 | |||
790 | #[test] | ||
791 | fn complete_attribute_in_source_file_end() { | ||
792 | check( | ||
793 | r#"#[$0]"#, | ||
794 | expect![[r#" | ||
795 | at allow(…) | ||
796 | at automatically_derived | ||
797 | at cfg(…) | ||
798 | at cfg_attr(…) | ||
799 | at cold | ||
800 | at deny(…) | ||
801 | at deprecated | ||
802 | at derive(…) | ||
803 | at doc = "…" | ||
804 | at doc(alias = "…") | ||
805 | at doc(hidden) | ||
806 | at export_name = "…" | ||
807 | at forbid(…) | ||
808 | at global_allocator | ||
809 | at ignore = "…" | ||
810 | at inline | ||
811 | at link | ||
812 | at link_name = "…" | ||
813 | at link_section = "…" | ||
814 | at macro_export | ||
815 | at macro_use | ||
816 | at must_use | ||
817 | at no_mangle | ||
818 | at non_exhaustive | ||
819 | at panic_handler | ||
820 | at path = "…" | ||
821 | at proc_macro | ||
822 | at proc_macro_attribute | ||
823 | at proc_macro_derive(…) | ||
824 | at repr(…) | ||
825 | at should_panic | ||
826 | at target_feature = "…" | ||
827 | at test | ||
828 | at track_caller | ||
829 | at used | ||
830 | at warn(…) | ||
831 | "#]], | ||
832 | ); | ||
833 | } | ||
784 | } | 834 | } |