|
5 | 5 |
|
6 | 6 | use once_cell::sync::Lazy;
|
7 | 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 | 10 | use crate::{
|
11 | 11 | context::CompletionContext,
|
@@ -37,15 +37,20 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext)
|
37 | 37 | }
|
38 | 38 |
|
39 | 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 | 47 | let attributes = attribute_annotated_item_kind.and_then(|kind| {
|
42 | 48 | if ast::Expr::can_cast(kind) {
|
43 | 49 | Some(EXPR_ATTRIBUTES)
|
44 | 50 | } else {
|
45 | 51 | KIND_TO_ATTRIBUTES.get(&kind).copied()
|
46 | 52 | }
|
47 | 53 | });
|
48 |
| - let is_inner = attribute.kind() == ast::AttrKind::Inner; |
49 | 54 |
|
50 | 55 | let add_completion = |attr_completion: &AttrCompletion| {
|
51 | 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 | }
|
0 commit comments