Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  lib.rs   Sprache: unbekannt

 
//! Weedle - A WebIDL Parser
//!
//! Parses valid WebIDL definitions & produces a data structure starting from
//! [`Definitions`](struct.Definitions.html).
//!
//! ### Example
//!
//! ```
//! extern crate weedle;
//!
//! let parsed = weedle::parse("
//!     interface Window {
//!         readonly attribute Storage sessionStorage;
//!     };
//! ").unwrap();
//! println!("{:?}", parsed);
//! ```
//!
//! Note:
//! This parser follows the grammar given at [WebIDL](https://heycam.github.io/webidl).
//!
//! If any flaws found when parsing string with a valid grammar, create an issue.

use self::argument::ArgumentList;
use self::attribute::ExtendedAttributeList;
use self::common::{Braced, Docstring, Identifier, Parenthesized, PunctuatedNonEmpty};
use self::dictionary::DictionaryMembers;
use self::interface::{Inheritance, InterfaceMembers};
use self::literal::StringLit;
use self::mixin::MixinMembers;
use self::namespace::NamespaceMembers;
use self::types::{AttributedType, ReturnType};
pub use nom::{error::Error, Err, IResult};

#[macro_use]
mod macros;
#[macro_use]
mod whitespace;
#[macro_use]
pub mod term;
pub mod argument;
pub mod attribute;
pub mod common;
pub mod dictionary;
pub mod interface;
pub mod literal;
pub mod mixin;
pub mod namespace;
pub mod types;

/// A convenient parse function
///
/// ### Example
///
/// ```
/// extern crate weedle;
///
/// let parsed = weedle::parse("
///     interface Window {
///         readonly attribute Storage sessionStorage;
///     };
/// ").unwrap();
///
/// println!("{:?}", parsed);
/// ```
pub fn parse(raw: &str) -> Result<Definitions<'_>, Err<Error<&str>>> {
    let (remaining, parsed) = Definitions::parse(raw)?;
    assert!(
        remaining.is_empty(),
        "There is redundant raw data after parsing"
    );
    Ok(parsed)
}

pub trait Parse<'a>: Sized {
    fn parse(input: &'a str) -> IResult<&'a str, Self>;
}

/// Parses WebIDL definitions. It is the root struct for a complete WebIDL definition.
///
/// ### Example
/// ```
/// use weedle::{Definitions, Parse};
///
/// let (_, parsed) = Definitions::parse("
///     interface Window {
///         readonly attribute Storage sessionStorage;
///     };
/// ").unwrap();
///
/// println!("{:?}", parsed);
/// ```
///
/// It is recommended to use [`parse`](fn.parse.html) instead.
pub type Definitions<'a> = Vec<Definition<'a>>;

ast_types! {
    /// Parses a definition
    enum Definition<'a> {
        /// Parses `[attributes]? callback identifier = type ( (arg1, arg2, ..., argN)? );`
        Callback(struct CallbackDefinition<'a> {
            attributes: Option<ExtendedAttributeList<'a>>,
            callback: term!(callback),
            identifier: Identifier<'a>,
            assign: term!(=),
            return_type: ReturnType<'a>,
            arguments: Parenthesized<ArgumentList<'a>>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? callback interface identifier ( : inheritance )? { members };`
        CallbackInterface(struct CallbackInterfaceDefinition<'a> {
            docstring: Option<Docstring>,
            attributes: Option<ExtendedAttributeList<'a>>,
            callback: term!(callback),
            interface: term!(interface),
            identifier: Identifier<'a>,
            inheritance: Option<Inheritance<'a>>,
            members: Braced<InterfaceMembers<'a>>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? interface identifier ( : inheritance )? { members };`
        Interface(struct InterfaceDefinition<'a> {
            docstring: Option<Docstring>,
            attributes: Option<ExtendedAttributeList<'a>>,
            interface: term!(interface),
            identifier: Identifier<'a>,
            inheritance: Option<Inheritance<'a>>,
            members: Braced<InterfaceMembers<'a>>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? interface mixin identifier { members };`
        InterfaceMixin(struct InterfaceMixinDefinition<'a> {
            attributes: Option<ExtendedAttributeList<'a>>,
            interface: term!(interface),
            mixin: term!(mixin),
            identifier: Identifier<'a>,
            members: Braced<MixinMembers<'a>>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? namespace identifier { members };`
        Namespace(struct NamespaceDefinition<'a> {
            docstring: Option<Docstring>,
            attributes: Option<ExtendedAttributeList<'a>>,
            namespace: term!(namespace),
            identifier: Identifier<'a>,
            members: Braced<NamespaceMembers<'a>>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? dictionary identifier ( : inheritance )? { members };`
        Dictionary(struct DictionaryDefinition<'a> {
            docstring: Option<Docstring>,
            attributes: Option<ExtendedAttributeList<'a>>,
            dictionary: term!(dictionary),
            identifier: Identifier<'a>,
            inheritance: Option<Inheritance<'a>>,
            members: Braced<DictionaryMembers<'a>>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? partial interface identifier { members };`
        PartialInterface(struct PartialInterfaceDefinition<'a> {
            attributes: Option<ExtendedAttributeList<'a>>,
            partial: term!(partial),
            interface: term!(interface),
            identifier: Identifier<'a>,
            members: Braced<InterfaceMembers<'a>>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? partial interface mixin identifier { members };`
        PartialInterfaceMixin(struct PartialInterfaceMixinDefinition<'a> {
            attributes: Option<ExtendedAttributeList<'a>>,
            partial: term!(partial),
            interface: term!(interface),
            mixin: term!(mixin),
            identifier: Identifier<'a>,
            members: Braced<MixinMembers<'a>>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? partial dictionary identifier { members };`
        PartialDictionary(struct PartialDictionaryDefinition<'a> {
            attributes: Option<ExtendedAttributeList<'a>>,
            partial: term!(partial),
            dictionary: term!(dictionary),
            identifier: Identifier<'a>,
            members: Braced<DictionaryMembers<'a>>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? partial namespace identifier { members };`
        PartialNamespace(struct PartialNamespaceDefinition<'a> {
            attributes: Option<ExtendedAttributeList<'a>>,
            partial: term!(partial),
            namespace: term!(namespace),
            identifier: Identifier<'a>,
            members: Braced<NamespaceMembers<'a>>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? enum identifier { values };`
        Enum(struct EnumDefinition<'a> {
            docstring: Option<Docstring>,
            attributes: Option<ExtendedAttributeList<'a>>,
            enum_: term!(enum),
            identifier: Identifier<'a>,
            values: Braced<EnumValueList<'a>>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? typedef attributedtype identifier;`
        Typedef(struct TypedefDefinition<'a> {
            attributes: Option<ExtendedAttributeList<'a>>,
            typedef: term!(typedef),
            type_: AttributedType<'a>,
            identifier: Identifier<'a>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? identifier includes identifier;`
        IncludesStatement(struct IncludesStatementDefinition<'a> {
            attributes: Option<ExtendedAttributeList<'a>>,
            lhs_identifier: Identifier<'a>,
            includes: term!(includes),
            rhs_identifier: Identifier<'a>,
            semi_colon: term!(;),
        }),
        /// Parses `[attributes]? identifier implements identifier;`
        Implements(struct ImplementsDefinition<'a> {
            attributes: Option<ExtendedAttributeList<'a>>,
            lhs_identifier: Identifier<'a>,
            includes: term!(implements),
            rhs_identifier: Identifier<'a>,
            semi_colon: term!(;),
        }),
    }
}

ast_types! {
    struct EnumVariant<'a> {
        docstring: Option<Docstring>,
        value: StringLit<'a>,
    }
}

/// Parses a non-empty enum value list
pub type EnumValueList<'a> = PunctuatedNonEmpty<EnumVariant<'a>, term!(,)>;

#[cfg(test)]
mod test {
    use super::*;

    test!(should_parse_includes_statement { "first includes second;" =>
        "";
        IncludesStatementDefinition;
        attributes.is_none();
        lhs_identifier.0 == "first";
        rhs_identifier.0 == "second";
    });

    test!(should_parse_typedef { "typedef short Short;" =>
        "";
        TypedefDefinition;
        attributes.is_none();
        identifier.0 == "Short";
    });

    test!(should_parse_enum { r#"enum name { "first", "second" }; "# =>
        "";
        EnumDefinition;
        attributes.is_none();
        identifier.0 == "name";
        values.body.list.len() == 2;
    });

    test!(should_parse_dictionary { "dictionary A { long c; long g; };" =>
        "";
        DictionaryDefinition;
        attributes.is_none();
        identifier.0 == "A";
        inheritance.is_none();
        members.body.len() == 2;
    });

    test!(should_parse_dictionary_inherited { "dictionary C : B { long e; long f; };" =>
        "";
        DictionaryDefinition;
        attributes.is_none();
        identifier.0 == "C";
        inheritance.is_some();
        members.body.len() == 2;
    });

    test!(should_parse_partial_namespace { "
        partial namespace VectorUtils {
            readonly attribute Vector unit;
            double dotProduct(Vector x, Vector y);
            Vector crossProduct(Vector x, Vector y);
        };
    " =>
        "";
        PartialNamespaceDefinition;
        attributes.is_none();
        identifier.0 == "VectorUtils";
        members.body.len() == 3;
    });

    test!(should_parse_partial_dictionary { "partial dictionary C { long e; long f; };" =>
        "";
        PartialDictionaryDefinition;
        attributes.is_none();
        identifier.0 == "C";
        members.body.len() == 2;
    });

    test!(should_parse_partial_interface_mixin { "
        partial interface mixin WindowSessionStorage {
          readonly attribute Storage sessionStorage;
        };
    " =>
        "";
        PartialInterfaceMixinDefinition;
        attributes.is_none();
        identifier.0 == "WindowSessionStorage";
        members.body.len() == 1;
    });

    test!(should_parse_partial_interface { "
        partial interface Window {
          readonly attribute Storage sessionStorage;
        };
    " =>
        "";
        PartialInterfaceDefinition;
        attributes.is_none();
        identifier.0 == "Window";
        members.body.len() == 1;
    });

    test!(should_parse_namespace { "
        namespace VectorUtils {
          readonly attribute Vector unit;
          double dotProduct(Vector x, Vector y);
          Vector crossProduct(Vector x, Vector y);
        };
    " =>
        "";
        NamespaceDefinition;
        attributes.is_none();
        identifier.0 == "VectorUtils";
        members.body.len() == 3;
    });

    test!(should_parse_interface_mixin { "
        interface mixin WindowSessionStorage {
          readonly attribute Storage sessionStorage;
        };
    " =>
        "";
        InterfaceMixinDefinition;
        attributes.is_none();
        identifier.0 == "WindowSessionStorage";
        members.body.len() == 1;
    });

    test!(should_parse_interface { "
        interface Window {
          readonly attribute Storage sessionStorage;
        };
    " =>
        "";
        InterfaceDefinition;
        attributes.is_none();
        identifier.0 == "Window";
        members.body.len() == 1;
    });

    test!(should_parse_callback_interface {"
        callback interface Options {
          attribute DOMString? option1;
          attribute DOMString? option2;
          attribute long? option3;
        };
    " =>
        "";
        CallbackInterfaceDefinition;
        attributes.is_none();
        identifier.0 == "Options";
        members.body.len() == 3;
    });

    test!(should_parse_callback { "callback AsyncOperationCallback = undefined (DOMString status);" =>
        "";
        CallbackDefinition;
        attributes.is_none();
        identifier.0 == "AsyncOperationCallback";
        arguments.body.list.len() == 1;
    });

    test!(should_parse_with_line_comments { "
        // This is a comment
        callback AsyncOperationCallback = undefined (DOMString status);
    " =>
        "";
        CallbackDefinition;
    });

    test!(should_parse_with_block_comments { "
        /* This is a comment */
        callback AsyncOperationCallback = undefined (DOMString status);
    " =>
        "";
        CallbackDefinition;
    });

    test!(should_parse_with_multiple_comments { "
        // This is a comment
        // This is a comment
        // This is a comment

        // This is a comment
        callback AsyncOperationCallback = undefined (DOMString status);
    " =>
        "";
        CallbackDefinition;
    });
}

[ Dauer der Verarbeitung: 0.24 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge