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 an attribute with an identifier. Ex: `PutForwards=name`
40        #[derive(Copy)]
41        Ident(struct ExtendedAttributeIdent<'a> {
42            lhs_identifier: Identifier<'a>,
43            assign: term!(=),
44            rhs: IdentifierOrString<'a>,
45        }),
46        /// Parses an attribute with a wildcard. Ex: `Exposed=*`
47        #[derive(Copy)]
48        Wildcard(struct ExtendedAttributeWildCard<'a> {
49            lhs_identifier: Identifier<'a>,
50            assign: term!(=),
51            rhs: term!(*),
52        }),
53        /// Parses a plain attribute. Ex: `Replaceable`
54        #[derive(Copy)]
55        NoArgs(struct ExtendedAttributeNoArgs<'a>(
56            Identifier<'a>,
57        )),
58    }
59
60    /// Parses `stringifier|static`
61    #[derive(Copy)]
62    enum IdentifierOrString<'a> {
63        Identifier(Identifier<'a>),
64        String(StringLit<'a>),
65    }
66}
67
68#[cfg(test)]
69mod test {
70    use super::*;
71    use crate::Parse;
72
73    test!(should_parse_attribute_no_args { "Replaceable" =>
74        "";
75        ExtendedAttributeNoArgs => ExtendedAttributeNoArgs(Identifier("Replaceable"))
76    });
77
78    test!(should_parse_attribute_arg_list { "Constructor(double x, double y)" =>
79        "";
80        ExtendedAttributeArgList;
81        identifier.0 == "Constructor";
82        args.body.list.len() == 2;
83    });
84
85    test!(should_parse_attribute_ident { "PutForwards=name" =>
86        "";
87        ExtendedAttributeIdent;
88        lhs_identifier.0 == "PutForwards";
89        rhs == IdentifierOrString::Identifier(Identifier("name"));
90    });
91
92    test!(should_parse_ident_list { "Exposed=(Window,Worker)" =>
93        "";
94        ExtendedAttributeIdentList;
95        identifier.0 == "Exposed";
96        list.body.list.len() == 2;
97    });
98
99    test!(should_parse_named_arg_list { "NamedConstructor=Image(DOMString src)" =>
100        "";
101        ExtendedAttributeNamedArgList;
102        lhs_identifier.0 == "NamedConstructor";
103        rhs_identifier.0 == "Image";
104        args.body.list.len() == 1;
105    });
106}