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
|
use crate::argument::ArgumentList;
use crate::common::{Bracketed, Identifier, Parenthesized, Punctuated};
use crate::literal::StringLit;
/// Parses a list of attributes. Ex: `[ attribute1, attribute2 ]`
pub type ExtendedAttributeList<'a> = Bracketed<Punctuated<ExtendedAttribute<'a>, term!(,)>>;
/// Matches comma separated identifier list
pub type IdentifierList<'a> = Punctuated<Identifier<'a>, term!(,)>;
ast_types! {
/// Parses on of the forms of attribute
enum ExtendedAttribute<'a> {
/// Parses an argument list. Ex: `Constructor((double x, double y))`
///
/// (( )) means ( ) chars
ArgList(struct ExtendedAttributeArgList<'a> {
identifier: Identifier<'a>,
args: Parenthesized<ArgumentList<'a>>,
}),
/// Parses a named argument list. Ex: `NamedConstructor=Image((DOMString src))`
///
/// (( )) means ( ) chars
NamedArgList(struct ExtendedAttributeNamedArgList<'a> {
lhs_identifier: Identifier<'a>,
assign: term!(=),
rhs_identifier: Identifier<'a>,
args: Parenthesized<ArgumentList<'a>>,
}),
/// Parses an identifier list. Ex: `Exposed=((Window,Worker))`
///
/// (( )) means ( ) chars
IdentList(struct ExtendedAttributeIdentList<'a> {
identifier: Identifier<'a>,
assign: term!(=),
list: Parenthesized<IdentifierList<'a>>,
}),
/// Parses an attribute with an identifier. Ex: `PutForwards=name`
#[derive(Copy)]
Ident(struct ExtendedAttributeIdent<'a> {
lhs_identifier: Identifier<'a>,
assign: term!(=),
rhs: IdentifierOrString<'a>,
}),
/// Parses a plain attribute. Ex: `Replaceable`
#[derive(Copy)]
NoArgs(struct ExtendedAttributeNoArgs<'a>(
Identifier<'a>,
)),
}
/// Parses `stringifier|static`
#[derive(Copy)]
enum IdentifierOrString<'a> {
Identifier(Identifier<'a>),
String(StringLit<'a>),
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::Parse;
test!(should_parse_attribute_no_args { "Replaceable" =>
"";
ExtendedAttributeNoArgs => ExtendedAttributeNoArgs(Identifier("Replaceable"))
});
test!(should_parse_attribute_arg_list { "Constructor(double x, double y)" =>
"";
ExtendedAttributeArgList;
identifier.0 == "Constructor";
args.body.list.len() == 2;
});
test!(should_parse_attribute_ident { "PutForwards=name" =>
"";
ExtendedAttributeIdent;
lhs_identifier.0 == "PutForwards";
rhs == IdentifierOrString::Identifier(Identifier("name"));
});
test!(should_parse_ident_list { "Exposed=(Window,Worker)" =>
"";
ExtendedAttributeIdentList;
identifier.0 == "Exposed";
list.body.list.len() == 2;
});
test!(should_parse_named_arg_list { "NamedConstructor=Image(DOMString src)" =>
"";
ExtendedAttributeNamedArgList;
lhs_identifier.0 == "NamedConstructor";
rhs_identifier.0 == "Image";
args.body.list.len() == 1;
});
}
|