diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-09-07 22:24:01 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-09-07 22:41:35 +0000 |
| commit | d76bf3ed80b0f6d6fb44704f98df1067353de300 (patch) | |
| tree | a785aa274d0341fedce7c62f0b50275c75af6840 /src/libsyntax | |
| parent | 3af0c6572eebd2c7fad72e8ba37eac71b8abc8bc (diff) | |
| download | rust-d76bf3ed80b0f6d6fb44704f98df1067353de300.tar.gz rust-d76bf3ed80b0f6d6fb44704f98df1067353de300.zip | |
Strip unconfigured nodes in the `InvocationCollector` fold.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/config.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 73 | ||||
| -rw-r--r-- | src/libsyntax/lib.rs | 1 |
3 files changed, 67 insertions, 19 deletions
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 07604bffa1c..3f5b294cc04 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -70,7 +70,7 @@ macro_rules! configure { } 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); 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 { abi: foreign_mod.abi, 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 { ast::ItemKind::Struct(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 { let arms = arms.into_iter().filter_map(|a| self.configure(a)).collect(); 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()); // 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) } - 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.configure(stmt) } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 0986d32ff56..68aca3ee32f 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -208,14 +208,23 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) { - let expansion = expansion.fold_with(&mut StripUnconfigured { - config: &self.cx.cfg, - should_test: self.cx.ecfg.should_test, - sess: self.cx.parse_sess, - features: self.cx.ecfg.features, - }); - let mut collector = InvocationCollector { cx: self.cx, invocations: Vec::new() }; - (expansion.fold_with(&mut collector), collector.invocations) + let crate_config = mem::replace(&mut self.cx.cfg, Vec::new()); + let result = { + let mut collector = InvocationCollector { + cfg: StripUnconfigured { + config: &crate_config, + should_test: self.cx.ecfg.should_test, + sess: self.cx.parse_sess, + 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 { @@ -403,9 +412,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> { struct InvocationCollector<'a, 'b: 'a> { cx: &'a mut ExtCtxt<'b>, + cfg: StripUnconfigured<'a>, 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> { fn collect(&mut self, expansion_kind: ExpansionKind, kind: InvocationKind) -> Expansion { let mark = Mark::fresh(); @@ -475,11 +494,17 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { } false } + + fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> { + self.cfg.configure(node) + } } impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { 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 { self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::Expr).make_expr() } 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>> { - 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 { self.collect_bang(mac, expr.attrs.into(), expr.span, ExpansionKind::OptExpr) .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> { + let stmt = match self.cfg.configure_stmt(stmt) { + Some(stmt) => stmt, + None => return SmallVector::zero(), + }; + let (mac, style, attrs) = match stmt.node { StmtKind::Mac(mac) => mac.unwrap(), _ => 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>> { + let item = configure!(self, item); + let (item, attr) = self.classify_item(item); 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(); } @@ -610,9 +644,12 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { } fn fold_trait_item(&mut self, item: ast::TraitItem) -> SmallVector<ast::TraitItem> { + let item = configure!(self, item); + let (item, attr) = self.classify_item(item); 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() } @@ -626,9 +663,11 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { } fn fold_impl_item(&mut self, item: ast::ImplItem) -> SmallVector<ast::ImplItem> { + let item = configure!(self, item); + let (item, attr) = self.classify_item(item); 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(); } @@ -653,6 +692,14 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { _ => 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> { diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 42201231247..4a2c9aff2d2 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -104,6 +104,7 @@ pub mod abi; pub mod ast; pub mod attr; pub mod codemap; +#[macro_use] pub mod config; pub mod entry; pub mod feature_gate; |
