Strip unconfigured nodes in the InvocationCollector
fold.
This commit is contained in:
parent
3af0c6572e
commit
d76bf3ed80
@ -70,7 +70,7 @@ macro_rules! configure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> StripUnconfigured<'a> {
|
impl<'a> StripUnconfigured<'a> {
|
||||||
fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
|
pub fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
|
||||||
let node = self.process_cfg_attrs(node);
|
let node = self.process_cfg_attrs(node);
|
||||||
if self.in_cfg(node.attrs()) { Some(node) } else { None }
|
if self.in_cfg(node.attrs()) { Some(node) } else { None }
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ impl<'a> StripUnconfigured<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
|
pub fn configure_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
|
||||||
ast::ForeignMod {
|
ast::ForeignMod {
|
||||||
abi: foreign_mod.abi,
|
abi: foreign_mod.abi,
|
||||||
items: foreign_mod.items.into_iter().filter_map(|item| self.configure(item)).collect(),
|
items: foreign_mod.items.into_iter().filter_map(|item| self.configure(item)).collect(),
|
||||||
@ -187,7 +187,7 @@ impl<'a> StripUnconfigured<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
|
pub fn configure_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
|
||||||
match item {
|
match item {
|
||||||
ast::ItemKind::Struct(def, generics) => {
|
ast::ItemKind::Struct(def, generics) => {
|
||||||
ast::ItemKind::Struct(self.configure_variant_data(def), generics)
|
ast::ItemKind::Struct(self.configure_variant_data(def), generics)
|
||||||
@ -217,7 +217,7 @@ impl<'a> StripUnconfigured<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_expr_kind(&mut self, expr_kind: ast::ExprKind) -> ast::ExprKind {
|
pub fn configure_expr_kind(&mut self, expr_kind: ast::ExprKind) -> ast::ExprKind {
|
||||||
if let ast::ExprKind::Match(m, arms) = expr_kind {
|
if let ast::ExprKind::Match(m, arms) = expr_kind {
|
||||||
let arms = arms.into_iter().filter_map(|a| self.configure(a)).collect();
|
let arms = arms.into_iter().filter_map(|a| self.configure(a)).collect();
|
||||||
ast::ExprKind::Match(m, arms)
|
ast::ExprKind::Match(m, arms)
|
||||||
@ -226,7 +226,7 @@ impl<'a> StripUnconfigured<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
|
pub fn configure_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
|
||||||
self.visit_stmt_or_expr_attrs(expr.attrs());
|
self.visit_stmt_or_expr_attrs(expr.attrs());
|
||||||
|
|
||||||
// If an expr is valid to cfg away it will have been removed by the
|
// If an expr is valid to cfg away it will have been removed by the
|
||||||
@ -244,7 +244,7 @@ impl<'a> StripUnconfigured<'a> {
|
|||||||
self.process_cfg_attrs(expr)
|
self.process_cfg_attrs(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_stmt(&mut self, stmt: ast::Stmt) -> Option<ast::Stmt> {
|
pub fn configure_stmt(&mut self, stmt: ast::Stmt) -> Option<ast::Stmt> {
|
||||||
self.visit_stmt_or_expr_attrs(stmt.attrs());
|
self.visit_stmt_or_expr_attrs(stmt.attrs());
|
||||||
self.configure(stmt)
|
self.configure(stmt)
|
||||||
}
|
}
|
||||||
|
@ -208,14 +208,23 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) {
|
fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) {
|
||||||
let expansion = expansion.fold_with(&mut StripUnconfigured {
|
let crate_config = mem::replace(&mut self.cx.cfg, Vec::new());
|
||||||
config: &self.cx.cfg,
|
let result = {
|
||||||
should_test: self.cx.ecfg.should_test,
|
let mut collector = InvocationCollector {
|
||||||
sess: self.cx.parse_sess,
|
cfg: StripUnconfigured {
|
||||||
features: self.cx.ecfg.features,
|
config: &crate_config,
|
||||||
});
|
should_test: self.cx.ecfg.should_test,
|
||||||
let mut collector = InvocationCollector { cx: self.cx, invocations: Vec::new() };
|
sess: self.cx.parse_sess,
|
||||||
(expansion.fold_with(&mut collector), collector.invocations)
|
features: self.cx.ecfg.features,
|
||||||
|
},
|
||||||
|
cx: self.cx,
|
||||||
|
invocations: Vec::new(),
|
||||||
|
};
|
||||||
|
(expansion.fold_with(&mut collector), collector.invocations)
|
||||||
|
};
|
||||||
|
|
||||||
|
self.cx.cfg = crate_config;
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_invoc(&mut self, invoc: Invocation) -> Expansion {
|
fn expand_invoc(&mut self, invoc: Invocation) -> Expansion {
|
||||||
@ -403,9 +412,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||||||
|
|
||||||
struct InvocationCollector<'a, 'b: 'a> {
|
struct InvocationCollector<'a, 'b: 'a> {
|
||||||
cx: &'a mut ExtCtxt<'b>,
|
cx: &'a mut ExtCtxt<'b>,
|
||||||
|
cfg: StripUnconfigured<'a>,
|
||||||
invocations: Vec<Invocation>,
|
invocations: Vec<Invocation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! fully_configure {
|
||||||
|
($this:ident, $node:ident, $noop_fold:ident) => {
|
||||||
|
match $noop_fold($node, &mut $this.cfg).pop() {
|
||||||
|
Some(node) => node,
|
||||||
|
None => return SmallVector::zero(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'b> InvocationCollector<'a, 'b> {
|
impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
fn collect(&mut self, expansion_kind: ExpansionKind, kind: InvocationKind) -> Expansion {
|
fn collect(&mut self, expansion_kind: ExpansionKind, kind: InvocationKind) -> Expansion {
|
||||||
let mark = Mark::fresh();
|
let mark = Mark::fresh();
|
||||||
@ -475,11 +494,17 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
|||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> {
|
||||||
|
self.cfg.configure(node)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
|
impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
|
||||||
fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
|
fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
|
||||||
let expr = expr.unwrap();
|
let mut expr = self.cfg.configure_expr(expr).unwrap();
|
||||||
|
expr.node = self.cfg.configure_expr_kind(expr.node);
|
||||||
|
|
||||||
if let ast::ExprKind::Mac(mac) = expr.node {
|
if let ast::ExprKind::Mac(mac) = expr.node {
|
||||||
self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::Expr).make_expr()
|
self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::Expr).make_expr()
|
||||||
} else {
|
} else {
|
||||||
@ -488,7 +513,9 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
|
fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
|
||||||
let expr = expr.unwrap();
|
let mut expr = configure!(self, expr).unwrap();
|
||||||
|
expr.node = self.cfg.configure_expr_kind(expr.node);
|
||||||
|
|
||||||
if let ast::ExprKind::Mac(mac) = expr.node {
|
if let ast::ExprKind::Mac(mac) = expr.node {
|
||||||
self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::OptExpr)
|
self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::OptExpr)
|
||||||
.make_opt_expr()
|
.make_opt_expr()
|
||||||
@ -511,6 +538,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
|
fn fold_stmt(&mut self, stmt: ast::Stmt) -> SmallVector<ast::Stmt> {
|
||||||
|
let stmt = match self.cfg.configure_stmt(stmt) {
|
||||||
|
Some(stmt) => stmt,
|
||||||
|
None => return SmallVector::zero(),
|
||||||
|
};
|
||||||
|
|
||||||
let (mac, style, attrs) = match stmt.node {
|
let (mac, style, attrs) = match stmt.node {
|
||||||
StmtKind::Mac(mac) => mac.unwrap(),
|
StmtKind::Mac(mac) => mac.unwrap(),
|
||||||
_ => return noop_fold_stmt(stmt, self),
|
_ => return noop_fold_stmt(stmt, self),
|
||||||
@ -540,9 +572,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
|
fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
|
||||||
|
let item = configure!(self, item);
|
||||||
|
|
||||||
let (item, attr) = self.classify_item(item);
|
let (item, attr) = self.classify_item(item);
|
||||||
if let Some(attr) = attr {
|
if let Some(attr) = attr {
|
||||||
let item = Annotatable::Item(item);
|
let item = Annotatable::Item(fully_configure!(self, item, noop_fold_item));
|
||||||
return self.collect_attr(attr, item, ExpansionKind::Items).make_items();
|
return self.collect_attr(attr, item, ExpansionKind::Items).make_items();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,9 +644,12 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitItem> {
|
fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitItem> {
|
||||||
|
let item = configure!(self, item);
|
||||||
|
|
||||||
let (item, attr) = self.classify_item(item);
|
let (item, attr) = self.classify_item(item);
|
||||||
if let Some(attr) = attr {
|
if let Some(attr) = attr {
|
||||||
let item = Annotatable::TraitItem(P(item));
|
let item =
|
||||||
|
Annotatable::TraitItem(P(fully_configure!(self, item, noop_fold_trait_item)));
|
||||||
return self.collect_attr(attr, item, ExpansionKind::TraitItems).make_trait_items()
|
return self.collect_attr(attr, item, ExpansionKind::TraitItems).make_trait_items()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,9 +663,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVector<ast::ImplItem> {
|
fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVector<ast::ImplItem> {
|
||||||
|
let item = configure!(self, item);
|
||||||
|
|
||||||
let (item, attr) = self.classify_item(item);
|
let (item, attr) = self.classify_item(item);
|
||||||
if let Some(attr) = attr {
|
if let Some(attr) = attr {
|
||||||
let item = Annotatable::ImplItem(P(item));
|
let item = Annotatable::ImplItem(P(fully_configure!(self, item, noop_fold_impl_item)));
|
||||||
return self.collect_attr(attr, item, ExpansionKind::ImplItems).make_impl_items();
|
return self.collect_attr(attr, item, ExpansionKind::ImplItems).make_impl_items();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,6 +692,14 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
|
||||||
|
noop_fold_foreign_mod(self.cfg.configure_foreign_mod(foreign_mod), self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_item_kind(&mut self, item: ast::ItemKind) -> ast::ItemKind {
|
||||||
|
noop_fold_item_kind(self.cfg.configure_item_kind(item), self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExpansionConfig<'feat> {
|
pub struct ExpansionConfig<'feat> {
|
||||||
|
@ -104,6 +104,7 @@ pub mod abi;
|
|||||||
pub mod ast;
|
pub mod ast;
|
||||||
pub mod attr;
|
pub mod attr;
|
||||||
pub mod codemap;
|
pub mod codemap;
|
||||||
|
#[macro_use]
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod entry;
|
pub mod entry;
|
||||||
pub mod feature_gate;
|
pub mod feature_gate;
|
||||||
|
Loading…
Reference in New Issue
Block a user