1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))]
#![deny(missing_docs)]

//! nue derive syntax extension.
//!
//! Provides the `#[derive(PodPacked, Pod, NueEncode, NueDecode)]` extensions documented in `nue-macros`.
//!
//! ## Stable
//!
//! See the [syntex documentation](https://github.com/erickt/rust-syntex/blob/master/README.md)
//! for instructions on how to set up your project to use these macros in stable Rust.
//!
//! ## Nightly / Unstable
//!
//! See the example in `nue-macros` for usage as a normal syntax extension.

extern crate aster;
extern crate quasi;
#[cfg(feature = "with-syntex")]
extern crate syntex;
#[cfg(feature = "with-syntex")]
extern crate syntex_syntax as syntax;
#[cfg(not(feature = "with-syntex"))]
extern crate syntax;
#[cfg(not(feature = "with-syntex"))]
extern crate rustc;

#[cfg(feature = "with-syntex")]
include!(concat!(env!("OUT_DIR"), "/lib.rs"));

#[cfg(not(feature = "with-syntex"))]
include!("lib.rs");

/// Registers the plugin for expansion with syntex.
#[cfg(feature = "with-syntex")]
pub fn register(reg: &mut syntex::Registry) {
    use syntax::{ast, fold};

    reg.add_attr("feature(custom_derive)");
    reg.add_attr("feature(custom_attribute)");

    reg.add_modifier("packed", expand_packed);
    reg.add_modifier("derive_PodPacked", expand_derive_pod_packed);
    reg.add_decorator("derive_Packed", expand_derive_packed);
    reg.add_decorator("derive_Pod", expand_derive_pod);
    reg.add_decorator("derive_NueEncode", expand_derive_encode);
    reg.add_decorator("derive_NueDecode", expand_derive_decode);

    reg.add_post_expansion_pass(strip_attributes);

    #[cfg(feature = "with-syntex")]
    fn strip_attributes(krate: ast::Crate) -> ast::Crate {
        struct StripAttributeFolder;

        impl fold::Folder for StripAttributeFolder {
            fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
                match attr.node.value.node {
                    ast::MetaWord(ref n) if *n == "__nue_packed" => { return None; },
                    ast::MetaList(ref n, _) if *n == "nue" || *n == "nue_enc" || *n == "nue_dec" => { return None; },
                    _ => {}
                }

                Some(attr)
            }

            fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
                fold::noop_fold_mac(mac, self)
            }
        }

        fold::Folder::fold_crate(&mut StripAttributeFolder, krate)
    }
}

#[doc(hidden)]
#[cfg(not(feature = "with-syntex"))]
pub fn register(reg: &mut rustc::plugin::Registry) {
    reg.register_syntax_extension(
        syntax::parse::token::intern("packed"),
        syntax::ext::base::MultiModifier(
            Box::new(expand_packed)
        )
    );

    reg.register_syntax_extension(
        syntax::parse::token::intern("derive_Packed"),
        syntax::ext::base::MultiDecorator(
            Box::new(expand_derive_packed)
        )
    );

    reg.register_syntax_extension(
        syntax::parse::token::intern("derive_PodPacked"),
        syntax::ext::base::MultiModifier(
            Box::new(expand_derive_pod_packed)
        )
    );

    reg.register_syntax_extension(
        syntax::parse::token::intern("derive_Pod"),
        syntax::ext::base::MultiDecorator(
            Box::new(expand_derive_pod)
        )
    );

    reg.register_syntax_extension(
        syntax::parse::token::intern("derive_NueEncode"),
        syntax::ext::base::MultiDecorator(
            Box::new(expand_derive_encode)
        )
    );

    reg.register_syntax_extension(
        syntax::parse::token::intern("derive_NueDecode"),
        syntax::ext::base::MultiDecorator(
            Box::new(expand_derive_decode)
        )
    );
}