aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src')
-rw-r--r--crates/ide_completion/src/completions/attribute.rs56
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
6use once_cell::sync::Lazy; 6use once_cell::sync::Lazy;
7use rustc_hash::{FxHashMap, FxHashSet}; 7use rustc_hash::{FxHashMap, FxHashSet};
8use syntax::{ast, AstNode, NodeOrToken, SyntaxKind, T}; 8use syntax::{algo::non_trivia_sibling, ast, AstNode, Direction, NodeOrToken, SyntaxKind, T};
9 9
10use crate::{ 10use 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
39fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attribute: &ast::Attr) { 39fn 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}