Refactor toggleable attributes
This commit is contained in:
parent
7e6528550d
commit
fa9404872e
2 changed files with 28 additions and 19 deletions
|
@ -1,4 +1,4 @@
|
|||
use syntax::ast::{Expr, Lit, Stmt, TokenTree, TtDelimited, TtToken};
|
||||
use syntax::ast::{Expr, ExprParen, Lit, Stmt, TokenTree, TtDelimited, TtToken};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::parse;
|
||||
|
@ -207,7 +207,14 @@ impl<'cx, 's, 'i> Parser<'cx, 's, 'i> {
|
|||
// Toggle the attribute based on a boolean expression
|
||||
self.shift(1);
|
||||
let cond = self.splice(tt.get_span());
|
||||
self.render.attribute_empty_if(name.as_str(), cond);
|
||||
// Silence "unnecessary parentheses" warnings
|
||||
let cond = strip_outer_parens(cond);
|
||||
let body = {
|
||||
let mut r = self.render.fork();
|
||||
r.attribute_empty(name.as_str());
|
||||
r.into_stmts()
|
||||
};
|
||||
self.render.emit_if(cond, body, None);
|
||||
} else {
|
||||
// Write the attribute unconditionally
|
||||
self.render.attribute_empty(name.as_str());
|
||||
|
@ -249,3 +256,11 @@ fn lit_to_string(cx: &ExtCtxt, lit: Lit, minus: bool) -> Option<String> {
|
|||
};
|
||||
Some(result)
|
||||
}
|
||||
|
||||
/// If the expression is wrapped in parentheses, strip them off.
|
||||
fn strip_outer_parens(expr: P<Expr>) -> P<Expr> {
|
||||
expr.and_then(|expr| match expr {
|
||||
Expr { node: ExprParen(inner), .. } => inner,
|
||||
expr => P(expr),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::borrow::IntoCow;
|
||||
use syntax::ast::{Expr, ExprParen, Ident, Stmt};
|
||||
use syntax::ast::{Expr, Ident, Stmt};
|
||||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::parse::token;
|
||||
|
@ -112,22 +112,6 @@ impl<'cx, 's> Renderer<'cx, 's> {
|
|||
self.write(name);
|
||||
}
|
||||
|
||||
pub fn attribute_empty_if(&mut self, name: &str, cond: P<Expr>) {
|
||||
// Silence "unnecessary parentheses" warnings
|
||||
let cond = match cond.node {
|
||||
ExprParen(ref inner) => inner.clone(),
|
||||
_ => cond.clone(),
|
||||
};
|
||||
let body = {
|
||||
let mut r = self.fork();
|
||||
r.write(" ");
|
||||
r.write(name);
|
||||
r.into_stmts()
|
||||
};
|
||||
let stmt = quote_stmt!(self.cx, if $cond { $body });
|
||||
self.stmts.push(stmt);
|
||||
}
|
||||
|
||||
pub fn attribute_end(&mut self) {
|
||||
self.write("\"");
|
||||
}
|
||||
|
@ -141,4 +125,14 @@ impl<'cx, 's> Renderer<'cx, 's> {
|
|||
self.write(name);
|
||||
self.write(">");
|
||||
}
|
||||
|
||||
pub fn emit_if(&mut self, cond: P<Expr>, if_body: Vec<P<Stmt>>,
|
||||
else_body: Option<Vec<P<Stmt>>>) {
|
||||
let stmt = match else_body {
|
||||
None => quote_stmt!(self.cx, if $cond { $if_body }),
|
||||
Some(else_body) =>
|
||||
quote_stmt!(self.cx, if $cond { $if_body } else { $else_body }),
|
||||
};
|
||||
self.stmts.push(stmt);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue