weedle/
attribute.rs

1use crate::argument::ArgumentList;
2use crate::common::{Bracketed, Identifier, Parenthesized, Punctuated};
3use crate::literal::StringLit;
4
5/// Parses a list of attributes. Ex: `[ attribute1, attribute2 ]`
6pub type ExtendedAttributeList<'a> = Bracketed<Punctuated<ExtendedAttribute<'a>, term!(,)>>;
7
8/// Matches comma separated identifier list
9pub type IdentifierList<'a> = Punctuated<Identifier<'a>, term!(,)>;
10
11ast_types! {
12    /// Parses on of the forms of attribute
13    enum ExtendedAttribute<'a> {
14        /// Parses an argument list. Ex: `Constructor((double x, double y))`
15        ///
16        /// (( )) means ( ) chars
17        ArgList(struct ExtendedAttributeArgList<'a> {
18            identifier: Identifier<'a>,
19            args: Parenthesized<ArgumentList<'a>>,
20        }),
21        /// Parses a named argument list. Ex: `NamedConstructor=Image((DOMString src))`
22        ///
23        /// (( )) means ( ) chars
24        NamedArgList(struct ExtendedAttributeNamedArgList<'a> {
25            lhs_identifier: Identifier<'a>,
26            assign: term!(=),
27            rhs_identifier: Identifier<'a>,
28            args: Parenthesized<ArgumentList<'a>>,
29
30        }),
31        /// Parses an identifier list. Ex: `Exposed=((Window,Worker))`
32        ///
33        /// (( )) means ( ) chars
34        IdentList(struct ExtendedAttributeIdentList<'a> {
35            identifier: Identifier<'a>,
36            assign: term!(=),
37            list: Parenthesized<IdentifierList<'a>>,
38        }),
39        /// Parses a wildcard. Ex: `[Exposed=*]`
40        WildCard(struct ExtendedAttributeWildcard<'a> {
41            identifier: Identifier<'a>,
42            assign: term!(=),
43            list: term!(*),
44        }),
45        /// Parses an attribute with an identifier. Ex: `PutForwards=name`
46        #[derive(Copy)]
47        Ident(struct ExtendedAttributeIdent<'a> {
48            lhs_identifier: Identifier<'a>,
49            assign: term!(=),
50            rhs: IdentifierOrString<'a>,
51        }),
52        /// Parses a plain attribute. Ex: `Replaceable`
53        #[derive(Copy)]
54        NoArgs(struct ExtendedAttributeNoArgs<'a>(
55            Identifier<'a>,
56        )),
57    }
58
59    /// Parses `stringifier|static`
60    #[derive(Copy)]
61    enum IdentifierOrString<'a> {
62        Identifier(Identifier<'a>),
63        String(StringLit<'a>),
64    }
65}
66
67#[cfg(test)]
68mod test {
69    use super::*;
70    use crate::Parse;
71
72    test!(should_parse_attribute_no_args { "Replaceable" =>
73        "";
74        ExtendedAttributeNoArgs => ExtendedAttributeNoArgs(Identifier("Replaceable"))
75    });
76
77    test!(should_parse_attribute_arg_list { "Constructor(double x, double y)" =>
78        "";
79        ExtendedAttributeArgList;
80        identifier.0 == "Constructor";
81        args.body.list.len() == 2;
82    });
83
84    test!(should_parse_attribute_ident { "PutForwards=name" =>
85        "";
86        ExtendedAttributeIdent;
87        lhs_identifier.0 == "PutForwards";
88        rhs == IdentifierOrString::Identifier(Identifier("name"));
89    });
90
91    test!(should_parse_ident_list { "Exposed=(Window,Worker)" =>
92        "";
93        ExtendedAttributeIdentList;
94        identifier.0 == "Exposed";
95        list.body.list.len() == 2;
96    });
97
98    test!(should_parse_wildcard { "Exposed=*" =>
99        "";
100        ExtendedAttributeWildcard;
101        identifier.0 == "Exposed";
102    });
103
104    test!(should_parse_named_arg_list { "NamedConstructor=Image(DOMString src)" =>
105        "";
106        ExtendedAttributeNamedArgList;
107        lhs_identifier.0 == "NamedConstructor";
108        rhs_identifier.0 == "Image";
109        args.body.list.len() == 1;
110    });
111}