diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-05-26 23:56:25 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-05-27 00:01:04 +0000 |
| commit | 15d5074a34976ad562acab0bc9c4a10754525b0a (patch) | |
| tree | 6e8dc3cd66ad918f90e226867e2ed830f55f58c4 /src/libsyntax | |
| parent | d3a0e1783c8e3ef336a684908fb08a0e8c0364d8 (diff) | |
Process `cfg_attr` attributes on non-optional expressions
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/config.rs | 66 | ||||
| -rw-r--r-- | src/libsyntax/test.rs | 9 |
2 files changed, 37 insertions, 38 deletions
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 62c922a4dbf..e1c17ca43d3 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -19,9 +19,15 @@ use ptr::P; use util::small_vector::SmallVector; pub trait CfgFolder: fold::Folder { - fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T>; + fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool; + fn process_attrs<T: HasAttrs>(&mut self, node: T) -> T { node } fn visit_stmt_or_expr_attrs(&mut self, _attrs: &[ast::Attribute]) {} - fn visit_unconfigurable_expr(&mut self, _expr: &ast::Expr) {} + fn visit_unremovable_expr(&mut self, _expr: &ast::Expr) {} + + fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> { + let node = self.process_attrs(node); + if self.in_cfg(node.attrs()) { Some(node) } else { None } + } } /// A folder that strips out items that do not belong in the current @@ -32,30 +38,6 @@ pub struct StripUnconfigured<'a> { } impl<'a> StripUnconfigured<'a> { - // Determine if an item should be translated in the current crate - // configuration based on the item's attributes - fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool { - attrs.iter().all(|attr| { - let mis = match attr.node.value.node { - ast::MetaItemKind::List(_, ref mis) if is_cfg(&attr) => mis, - _ => return true - }; - - if mis.len() != 1 { - self.diag.emit_error(|diagnostic| { - diagnostic.span_err(attr.span, "expected 1 cfg-pattern"); - }); - return true; - } - - attr::cfg_matches(self.config, &mis[0], &mut self.diag) - }) - } - - fn process_cfg_attrs(&mut self, attrs: Vec<ast::Attribute>) -> Vec<ast::Attribute> { - attrs.into_iter().filter_map(|attr| self.process_cfg_attr(attr)).collect() - } - fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> { if !attr.check_name("cfg_attr") { return Some(attr); @@ -92,9 +74,30 @@ impl<'a> StripUnconfigured<'a> { } impl<'a> CfgFolder for StripUnconfigured<'a> { - fn configure<T: HasAttrs>(&mut self, node: T) -> Option<T> { - let node = node.map_attrs(|attrs| self.process_cfg_attrs(attrs)); - if self.in_cfg(node.attrs()) { Some(node) } else { None } + // Determine if an item should be translated in the current crate + // configuration based on the item's attributes + fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool { + attrs.iter().all(|attr| { + let mis = match attr.node.value.node { + ast::MetaItemKind::List(_, ref mis) if is_cfg(&attr) => mis, + _ => return true + }; + + if mis.len() != 1 { + self.diag.emit_error(|diagnostic| { + diagnostic.span_err(attr.span, "expected 1 cfg-pattern"); + }); + return true; + } + + attr::cfg_matches(self.config, &mis[0], &mut self.diag) + }) + } + + fn process_attrs<T: HasAttrs>(&mut self, node: T) -> T { + node.map_attrs(|attrs| { + attrs.into_iter().filter_map(|attr| self.process_cfg_attr(attr)).collect() + }) } fn visit_stmt_or_expr_attrs(&mut self, attrs: &[ast::Attribute]) { @@ -104,7 +107,7 @@ impl<'a> CfgFolder for StripUnconfigured<'a> { } } - fn visit_unconfigurable_expr(&mut self, expr: &ast::Expr) { + fn visit_unremovable_expr(&mut self, expr: &ast::Expr) { if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) { let msg = "removing an expression is not supported in this position"; self.diag.diag.span_err(attr.span, msg); @@ -195,7 +198,8 @@ impl<T: CfgFolder> fold::Folder for T { // // NB: This is intentionally not part of the fold_expr() function // in order for fold_opt_expr() to be able to avoid this check - self.visit_unconfigurable_expr(&expr); + self.visit_unremovable_expr(&expr); + let expr = self.process_attrs(expr); fold_expr(self, expr) } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 84c7250fac6..45f349eff31 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -317,13 +317,8 @@ fn strip_test_functions(krate: ast::Crate) -> ast::Crate { // #[test] functions struct StripTests; impl config::CfgFolder for StripTests { - fn configure<T: attr::HasAttrs>(&mut self, node: T) -> Option<T> { - let strip_node = { - let attrs = node.attrs(); - attr::contains_name(attrs, "test") || attr::contains_name(attrs, "bench") - }; - - if strip_node { None } else { Some(node) } + fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool { + !attr::contains_name(attrs, "test") && !attr::contains_name(attrs, "bench") } } |
