1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use sway_ast::Literal;
use sway_types::{
constants::{ALLOW_DEAD_CODE_NAME, CFG_TARGET_ARG_NAME},
Ident, Span, Spanned,
};
use std::{collections::HashMap, hash::Hash, sync::Arc};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AttributeArg {
pub name: Ident,
pub value: Option<Literal>,
pub span: Span,
}
impl Spanned for AttributeArg {
fn span(&self) -> Span {
self.span.clone()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Attribute {
pub name: Ident,
pub args: Vec<AttributeArg>,
pub span: Span,
}
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum AttributeKind {
Doc,
DocComment,
Storage,
Inline,
Test,
Payable,
Allow,
Cfg,
}
impl AttributeKind {
pub fn expected_args_len_min_max(self) -> (usize, Option<usize>) {
match self {
AttributeKind::Doc => (0, None),
AttributeKind::DocComment => (0, None),
AttributeKind::Storage => (0, None),
AttributeKind::Inline => (0, None),
AttributeKind::Test => (0, None),
AttributeKind::Payable => (0, None),
AttributeKind::Allow => (1, Some(1)),
AttributeKind::Cfg => (1, Some(1)),
}
}
pub fn expected_args_values(self, _arg_index: usize) -> Option<Vec<String>> {
match self {
AttributeKind::Doc => None,
AttributeKind::DocComment => None,
AttributeKind::Storage => None,
AttributeKind::Inline => None,
AttributeKind::Test => None,
AttributeKind::Payable => None,
AttributeKind::Allow => Some(vec![ALLOW_DEAD_CODE_NAME.to_string()]),
AttributeKind::Cfg => Some(vec![CFG_TARGET_ARG_NAME.to_string()]),
}
}
}
#[derive(Default, Clone, Debug, Eq, PartialEq)]
pub struct AttributesMap(Arc<HashMap<AttributeKind, Vec<Attribute>>>);
impl AttributesMap {
pub fn new(attrs_map: Arc<HashMap<AttributeKind, Vec<Attribute>>>) -> AttributesMap {
AttributesMap(attrs_map)
}
pub fn first(&self) -> Option<(&AttributeKind, &Attribute)> {
let mut first: Option<(&AttributeKind, &Attribute)> = None;
for (kind, attrs) in self.iter() {
for attr in attrs {
if let Some((_, first_attr)) = first {
if attr.span.start() < first_attr.span.start() {
first = Some((kind, attr));
}
} else {
first = Some((kind, attr));
}
}
}
first
}
pub fn inner(&self) -> &HashMap<AttributeKind, Vec<Attribute>> {
&self.0
}
}
impl std::ops::Deref for AttributesMap {
type Target = Arc<HashMap<AttributeKind, Vec<Attribute>>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}