diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-06-12 13:38:39 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-06-16 03:55:53 +0000 |
| commit | 34191ed1c8484bb2feb14369fd638c2671854c70 (patch) | |
| tree | 09f3b6fe2b7dcb50f5d4f7d05ecc9dbbbc54b9ec /src/libsyntax/ext | |
| parent | 6ba7b7c22d3e37572118f7afa394216ec9cd898b (diff) | |
| download | rust-34191ed1c8484bb2feb14369fd638c2671854c70.tar.gz rust-34191ed1c8484bb2feb14369fd638c2671854c70.zip | |
Refactor MultiModifier expansion
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 99 |
1 files changed, 34 insertions, 65 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 83ddc79af84..e7d7b0a6aef 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -13,6 +13,7 @@ use ast::{Local, Ident, Mac_, Name, SpannedIdent}; use ast::{MacStmtStyle, Mrk, Stmt, StmtKind, ItemKind}; use ast::TokenTree; use ast; +use attr::HasAttrs; use ext::mtwt; use ext::build::AstBuilder; use attr; @@ -712,11 +713,7 @@ impl<'a> Folder for PatIdentRenamer<'a> { } } -fn expand_annotatable(a: Annotatable, - fld: &mut MacroExpander) - -> SmallVector<Annotatable> { - let a = expand_item_multi_modifier(a, fld); - +fn expand_multi_modified(a: Annotatable, fld: &mut MacroExpander) -> SmallVector<Annotatable> { let new_items: SmallVector<Annotatable> = match a { Annotatable::Item(it) => match it.node { ast::ItemKind::Mac(..) => { @@ -795,29 +792,6 @@ fn decorate(a: Annotatable, fld: &mut MacroExpander) -> SmallVector<Annotatable> new_items } -// Partition a set of attributes into one kind of attribute, and other kinds. -macro_rules! partition { - ($fn_name: ident, $variant: ident) => { - #[allow(deprecated)] // The `allow` is needed because the `Modifier` variant might be used. - fn $fn_name(attrs: &[ast::Attribute], - fld: &MacroExpander) - -> (Vec<ast::Attribute>, Vec<ast::Attribute>) { - attrs.iter().cloned().partition(|attr| { - match fld.cx.syntax_env.find(intern(&attr.name())) { - Some(rc) => match *rc { - $variant(..) => true, - _ => false - }, - _ => false - } - }) - } - } -} - -partition!(multi_modifiers, MultiModifier); - - fn expand_decorators(a: Annotatable, fld: &mut MacroExpander, decorator_items: &mut SmallVector<Annotatable>, @@ -861,46 +835,41 @@ fn expand_decorators(a: Annotatable, } } -fn expand_item_multi_modifier(mut it: Annotatable, - fld: &mut MacroExpander) - -> Annotatable { - let (modifiers, other_attrs) = multi_modifiers(it.attrs(), fld); - - // Update the attrs, leave everything else alone. Is this mutation really a good idea? - it = it.fold_attrs(other_attrs); - - if modifiers.is_empty() { - return it - } - - for attr in &modifiers { - let mname = intern(&attr.name()); - - match fld.cx.syntax_env.find(mname) { - Some(rc) => match *rc { - MultiModifier(ref mac) => { - attr::mark_used(attr); - fld.cx.bt_push(ExpnInfo { - call_site: attr.span, - callee: NameAndSpan { - format: MacroAttribute(mname), - span: Some(attr.span), - // attributes can do whatever they like, - // for now - allow_internal_unstable: true, - } - }); - it = mac.expand(fld.cx, attr.span, &attr.node.value, it); - fld.cx.bt_pop(); +fn expand_annotatable(mut item: Annotatable, fld: &mut MacroExpander) -> SmallVector<Annotatable> { + let mut multi_modifier = None; + item = item.map_attrs(|mut attrs| { + for i in 0..attrs.len() { + if let Some(extension) = fld.cx.syntax_env.find(intern(&attrs[i].name())) { + if let MultiModifier(..) = *extension { + multi_modifier = Some((attrs.remove(i), extension)); + break; } - _ => unreachable!() - }, - _ => unreachable!() + } } - } + attrs + }); - // Expansion may have added new ItemKind::Modifiers. - expand_item_multi_modifier(it, fld) + match multi_modifier { + None => expand_multi_modified(item, fld), + Some((attr, extension)) => match *extension { + MultiModifier(ref mac) => { + attr::mark_used(&attr); + fld.cx.bt_push(ExpnInfo { + call_site: attr.span, + callee: NameAndSpan { + format: MacroAttribute(intern(&attr.name())), + span: Some(attr.span), + // attributes can do whatever they like, for now + allow_internal_unstable: true, + } + }); + let modified = mac.expand(fld.cx, attr.span, &attr.node.value, item); + fld.cx.bt_pop(); + expand_annotatable(modified, fld) + } + _ => unreachable!(), + } + } } fn expand_impl_item(ii: ast::ImplItem, fld: &mut MacroExpander) |
