use crate::argument::ArgumentList; use crate::attribute::ExtendedAttributeList; use crate::common::{Generics, Identifier, Parenthesized}; use crate::literal::ConstValue; use crate::types::{AttributedType, ConstType, ReturnType}; /// Parses interface members pub type InterfaceMembers<'a> = Vec>; ast_types! { /// Parses inheritance clause `: identifier` #[derive(Copy)] struct Inheritance<'a> { colon: term!(:), identifier: Identifier<'a>, } /// Parses one of the interface member variants enum InterfaceMember<'a> { /// Parses a const interface member `[attributes]? const type identifier = value;` Const(struct ConstMember<'a> { attributes: Option>, const_: term!(const), const_type: ConstType<'a>, identifier: Identifier<'a>, assign: term!(=), const_value: ConstValue<'a>, semi_colon: term!(;), }), /// Parses `[attributes]? (stringifier|inherit|static)? readonly? attribute attributedtype identifier;` Attribute(struct AttributeInterfaceMember<'a> { attributes: Option>, modifier: Option, readonly: Option, attribute: term!(attribute), type_: AttributedType<'a>, identifier: Identifier<'a>, semi_colon: term!(;), }), /// Parses `[attributes]? constructor(( args ));` /// /// (( )) means ( ) chars Constructor(struct ConstructorInterfaceMember<'a> { attributes: Option>, constructor: term!(constructor), args: Parenthesized>, semi_colon: term!(;), }), /// Parses `[attributes]? (stringifier|static)? special? returntype identifier? (( args ));` /// /// (( )) means ( ) chars Operation(struct OperationInterfaceMember<'a> { attributes: Option>, modifier: Option, special: Option, return_type: ReturnType<'a>, identifier: Option>, args: Parenthesized>, semi_colon: term!(;), }), /// Parses an iterable declaration `[attributes]? (iterable | iterable) ;` Iterable(enum IterableInterfaceMember<'a> { /// Parses an iterable declaration `[attributes]? iterable;` Single(struct SingleTypedIterable<'a> { attributes: Option>, iterable: term!(iterable), generics: Generics>, semi_colon: term!(;), }), /// Parses an iterable declaration `[attributes]? iterable;` Double(struct DoubleTypedIterable<'a> { attributes: Option>, iterable: term!(iterable), generics: Generics<(AttributedType<'a>, term!(,), AttributedType<'a>)>, semi_colon: term!(;), }), }), /// Parses an async iterable declaration `[attributes]? async (iterable | iterable) (( args ))? ;` AsyncIterable(enum AsyncIterableInterfaceMember<'a> { /// Parses an async iterable declaration `[attributes]? async iterable (( args ))? ;` Single(struct SingleTypedAsyncIterable<'a> { attributes: Option>, async_iterable: (term!(async), term!(iterable)), generics: Generics>, args: Option>>, semi_colon: term!(;), }), /// Parses an async iterable declaration `[attributes]? async iterable (( args ))? ;` Double(struct DoubleTypedAsyncIterable<'a> { attributes: Option>, async_iterable: (term!(async), term!(iterable)), generics: Generics<(AttributedType<'a>, term!(,), AttributedType<'a>)>, args: Option>>, semi_colon: term!(;), }), }), /// Parses an maplike declaration `[attributes]? readonly? maplike;` Maplike(struct MaplikeInterfaceMember<'a> { attributes: Option>, readonly: Option, maplike: term!(maplike), generics: Generics<(AttributedType<'a>, term!(,), AttributedType<'a>)>, semi_colon: term!(;), }), Setlike(struct SetlikeInterfaceMember<'a> { attributes: Option>, readonly: Option, setlike: term!(setlike), generics: Generics>, semi_colon: term!(;), }), /// Parses `stringifier;` #[derive(Default)] Stringifier(struct StringifierMember<'a> { attributes: Option>, stringifier: term!(stringifier), semi_colon: term!(;), }), } /// Parses one of the special keyword `getter|setter|deleter` #[derive(Copy)] enum Special { Getter(term!(getter)), Setter(term!(setter)), Deleter(term!(deleter)), LegacyCaller(term!(legacycaller)), } /// Parses `stringifier|inherit|static` #[derive(Copy)] enum StringifierOrInheritOrStatic { Stringifier(term!(stringifier)), Inherit(term!(inherit)), Static(term!(static)), } /// Parses `stringifier|static` #[derive(Copy)] enum StringifierOrStatic { Stringifier(term!(stringifier)), Static(term!(static)), } } #[cfg(test)] mod test { use super::*; use crate::Parse; test!(should_parse_stringifier_member { "stringifier;" => ""; StringifierMember; }); test!(should_parse_stringifier_or_static { "static" => ""; StringifierOrStatic; }); test!(should_parse_stringifier_or_inherit_or_static { "inherit" => ""; StringifierOrInheritOrStatic; }); test!(should_parse_setlike_interface_member { "readonly setlike;" => ""; SetlikeInterfaceMember; attributes.is_none(); readonly == Some(term!(readonly)); }); test!(should_parse_maplike_interface_member { "readonly maplike;" => ""; MaplikeInterfaceMember; attributes.is_none(); readonly == Some(term!(readonly)); }); test!(should_parse_attribute_interface_member { "readonly attribute unsigned long width;" => ""; AttributeInterfaceMember; attributes.is_none(); readonly == Some(term!(readonly)); identifier.0 == "width"; }); test!(should_parse_double_typed_iterable { "iterable;" => ""; DoubleTypedIterable; attributes.is_none(); }); test!(should_parse_single_typed_iterable { "iterable;" => ""; SingleTypedIterable; attributes.is_none(); }); test!(should_parse_double_typed_async_iterable { "async iterable;" => ""; DoubleTypedAsyncIterable; attributes.is_none(); args.is_none(); }); test!(should_parse_double_typed_async_iterable_with_args { "async iterable(long a);" => ""; DoubleTypedAsyncIterable; attributes.is_none(); args.is_some(); }); test!(should_parse_single_typed_async_iterable { "async iterable;" => ""; SingleTypedAsyncIterable; attributes.is_none(); args.is_none(); }); test!(should_parse_single_typed_async_iterable_with_args { "async iterable(long a);" => ""; SingleTypedAsyncIterable; attributes.is_none(); args.is_some(); }); test!(should_parse_constructor_interface_member { "constructor(long a);" => ""; ConstructorInterfaceMember; attributes.is_none(); }); test!(should_parse_operation_interface_member { "undefined readString(long a, long b);" => ""; OperationInterfaceMember; attributes.is_none(); modifier.is_none(); special.is_none(); identifier.is_some(); }); test!(should_parse_const_member { "const long name = 5;" => ""; ConstMember; attributes.is_none(); identifier.0 == "name"; }); }