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
use smallvec::SmallVec;
use crate::diag::location::{SourceLoc, SourceRange};
use crate::syntax::id::Identifier;
#[cfg_attr(test, derive(Debug))]
pub struct Attribute<'a> {
pub items: SmallVec<[AttrItem<'a>; 4]>,
pub hash_loc: SourceLoc,
pub exclaim_loc: SourceLoc,
pub left_bracket_loc: SourceLoc,
pub right_bracket_loc: SourceLoc
}
#[cfg_attr(test, derive(Debug))]
pub enum AttrItem<'a> {
IdentifierItem(Identifier<'a>),
AssignLikeItem(AttrAssignLikeItem<'a>),
CallLikeItem(AttrCallLikeItem<'a>)
}
#[cfg_attr(test, derive(Debug))]
pub struct AttrAssignLikeItem<'a> {
pub ident: Identifier<'a>,
pub value: AttrValue<'a>,
pub assign_loc: SourceLoc,
}
#[cfg_attr(test, derive(Debug))]
pub struct AttrCallLikeItem<'a> {
pub ident: Identifier<'a>,
pub args: Vec<AttrItem<'a>>,
pub left_paren_loc: SourceLoc,
pub right_paren_loc: SourceLoc,
}
#[cfg_attr(test, derive(Debug))]
pub struct AttrValue<'a> {
pub inner: AttrValueInner<'a>,
pub range: SourceRange
}
#[cfg_attr(test, derive(Debug))]
pub enum AttrValueInner<'a> {
Identifier(Identifier<'a>),
IntLiteral(i64),
FloatLiteral(f64),
CharLiteral(char),
StringLiteral(&'a str),
BoolLiteral(bool)
}
impl<'a> AttrValue<'a> {
pub fn ident_value(ident: Identifier<'a>) -> Self {
Self {
inner: AttrValueInner::Identifier(ident),
range: SourceRange::unknown()
}
}
pub fn int_value(value: i64, range: SourceRange) -> Self {
Self {
inner: AttrValueInner::IntLiteral(value),
range
}
}
pub fn float_value(value: f64, range: SourceRange) -> Self {
Self {
inner: AttrValueInner::FloatLiteral(value),
range
}
}
pub fn char_value(value: char, range: SourceRange) -> Self {
Self {
inner: AttrValueInner::CharLiteral(value),
range
}
}
pub fn string_value(value: &'a str, range: SourceRange) -> Self {
Self {
inner: AttrValueInner::StringLiteral(value),
range
}
}
pub fn bool_value(value: bool, range: SourceRange) -> Self {
Self {
inner: AttrValueInner::BoolLiteral(value),
range
}
}
}