#![feature(plugin_registrar, quote, box_syntax)]
#![deny(missing_copy_implementations)]
#![allow(unstable)]
extern crate rustc;
extern crate syntax;
use syntax::{ast, attr, ext, codemap};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::fold::Folder;
use syntax::ptr::P;
pub mod shader_param;
pub mod vertex_format;
#[plugin_registrar]
pub fn registrar(reg: &mut rustc::plugin::Registry) {
use syntax::parse::token::intern;
use syntax::ext::base;
reg.register_syntax_extension(intern("shader_param"),
base::Decorator(box shader_param::ShaderParam));
reg.register_syntax_extension(intern("vertex_format"),
base::Decorator(box vertex_format::VertexFormat));
}
fn find_name(cx: &mut ext::base::ExtCtxt, span: codemap::Span,
attributes: &[ast::Attribute]) -> Option<token::InternedString> {
attributes.iter().fold(None, |name, attribute| {
match attribute.node.value.node {
ast::MetaNameValue(ref attr_name, ref attr_value) => {
match (attr_name.get(), &attr_value.node) {
("name", &ast::LitStr(ref new_name, _)) => {
attr::mark_used(attribute);
name.map_or(Some(new_name.clone()), |name| {
cx.span_warn(span, &format!(
"Extra field name detected: {:?} - \
ignoring in favour of: {:?}", new_name, name
)[]);
None
})
}
_ => None,
}
}
_ => name,
}
})
}
static EXTERN_CRATE_HACK: &'static str = "__gfx_extern_crate_hack";
fn extern_crate_hack<F>(context: &mut ext::base::ExtCtxt,
span: codemap::Span,
mut push: F) -> ast::Ident where F: FnMut(P<ast::Item>) {
let extern_crate_hack = token::gensym_ident(EXTERN_CRATE_HACK);
let item = context.item_mod(
span,
span,
extern_crate_hack,
vec![],
vec![
P(ast::Item {
span: span,
vis: ast::Inherited,
attrs: vec![],
node: ast::ItemExternCrate(
Some((
token::InternedString::new("gfx"),
ast::CookedStr
)),
),
id: ast::DUMMY_NODE_ID,
ident: token::str_to_ident("gfx_")
}),
context.item_use_simple_(
span,
ast::Public,
context.ident_of("gfx"),
context.path(span, vec![
context.ident_of("self"),
context.ident_of("gfx_")
])
)
]
);
push(item);
extern_crate_hack
}
struct ExternCrateHackFolder {
path_root: ast::Ident
}
impl Folder for ExternCrateHackFolder {
fn fold_path(&mut self, p: ast::Path) -> ast::Path {
let p = syntax::fold::noop_fold_path(p, self);
let needs_fix = (&p.segments[]).get(0)
.map(|s| s.identifier.as_str() == EXTERN_CRATE_HACK)
.unwrap_or(false);
let needs_fix_self = (&p.segments[]).get(0)
.map(|s| s.identifier.as_str() == "self")
.unwrap_or(false) &&
(&p.segments[]).get(1)
.map(|s| s.identifier.as_str() == EXTERN_CRATE_HACK)
.unwrap_or(false);
if needs_fix {
let mut p = p.clone();
p.segments[0].identifier = self.path_root;
p.global = false;
p
} else if needs_fix_self {
let mut p = p.clone();
p.segments[1].identifier = self.path_root;
p.global = false;
p
} else {
p
}
}
}
fn fixup_extern_crate_paths(item: P<ast::Item>, path_root: ast::Ident) -> P<ast::Item> {
ExternCrateHackFolder {
path_root: path_root
}.fold_item(item).into_iter().next().unwrap()
}
#[macro_export]
macro_rules! shaders {
(targets : $v:expr) => {
{
use gfx;
gfx::ShaderSource {
targets: $v,
..shaders!()
}
}
};
(targets : $v:expr, $($t:tt)*) => {
{
use gfx;
gfx::ShaderSource {
targets: $v,
..shaders!($($t)*)
}
}
};
($i:ident : $v:expr) => {
{
use gfx;
gfx::ShaderSource {
$i: Some($v),
..shaders!()
}
}
};
($i:ident : $v:expr, $($t:tt)*) => {
{
use gfx;
gfx::ShaderSource {
$i: Some($v),
..shaders!($($t)*)
}
}
};
() => {
{
use gfx;
gfx::ShaderSource {
glsl_120: None,
glsl_130: None,
glsl_140: None,
glsl_150: None,
targets: &[],
}
}
}
}