[go: up one dir, main page]

syntex 0.4.1

High-level bindings to the zeromq library
extern crate syntex_syntax;

use std::fs::File;
use std::io;
use std::path::Path;

use syntex_syntax::ast::MacroDef;
use syntex_syntax::config;
use syntex_syntax::ext::base::{
    IdentMacroExpander,
    ItemDecorator,
    ItemModifier,
    MultiItemModifier,
    NamedSyntaxExtension,
    SyntaxExtension,
    TTMacroExpander,
};
use syntex_syntax::ext::expand;
use syntex_syntax::parse::{self, token};
use syntex_syntax::print::{pp, pprust};

pub struct Registry {
    macros: Vec<MacroDef>,
    syntax_exts: Vec<NamedSyntaxExtension>,
}

impl Registry {
    pub fn new() -> Registry {
        Registry {
            macros: Vec::new(),
            syntax_exts: Vec::new(),
        }
    }

    pub fn with_standard_macros() -> Registry {
        let registry = Registry::new();
        registry
    }

    pub fn register_macro<F>(&mut self, name: &str, extension: F)
        where F: TTMacroExpander + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::NormalTT(
            Box::new(extension),
            None,
            false
        );
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn register_ident<F>(&mut self, name: &str, extension: F)
        where F: IdentMacroExpander + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::IdentTT(
            Box::new(extension),
            None,
            false
        );
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn register_decorator<F>(&mut self, name: &str, extension: F)
        where F: ItemDecorator + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::Decorator(Box::new(extension));
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn register_item_modifier<F>(&mut self, name: &str, extension: F)
        where F: ItemModifier + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::Modifier(Box::new(extension));
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn register_multi_item_modifier<F>(&mut self, name: &str, extension: F)
        where F: MultiItemModifier + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::MultiModifier(Box::new(extension));
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn expand(self, crate_name: &str, src: &Path, dst: &Path) -> io::Result<()> {
        let sess = parse::new_parse_sess();
        let cfg = vec![];

        let krate = parse::parse_crate_from_file(
            src,
            cfg,
            &sess);

        let krate = config::strip_unconfigured_items(
            &sess.span_diagnostic,
            krate);

        let cfg = expand::ExpansionConfig::default(crate_name.to_string());

        let krate = expand::expand_crate(
            &sess,
            cfg,
            self.macros,
            self.syntax_exts,
            krate);

        let dst = try!(File::create(dst));

        let mut printer = pprust::rust_printer(Box::new(dst));
        try!(printer.print_mod(&krate.module, &krate.attrs[..]));
        try!(printer.print_remaining_comments());
        pp::eof(&mut printer.s)
    }
}