(index<- )        ./libsyntax/ext/registrar.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Sat Apr 19 11:22:39 2014
  1  // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
  2  // file at the top-level directory of this distribution and at
  3  // http://rust-lang.org/COPYRIGHT.
  4  //
  5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8  // option. This file may not be copied, modified, or distributed
  9  // except according to those terms.
 10  
 11  use ast;
 12  use attr;
 13  use codemap::Span;
 14  use diagnostic;
 15  use visit;
 16  use visit::Visitor;
 17  
 18  struct MacroRegistrarContext {
 19      registrars: Vec<(ast::NodeId, Span)> ,
 20  }
 21  
 22  impl Visitor<()> for MacroRegistrarContext {
 23      fn visit_item(&mut self, item&ast::Item, _()) {
 24          match item.node {
 25              ast::ItemFn(..) => {
 26                  if attr::contains_name(item.attrs.as_slice(),
 27                                         "macro_registrar") {
 28                      self.registrars.push((item.id, item.span));
 29                  }
 30              }
 31              _ => {}
 32          }
 33  
 34          visit::walk_item(self, item, ());
 35      }
 36  }
 37  
 38  pub fn find_macro_registrar(diagnostic: &diagnostic::SpanHandler,
 39                              krate: &ast::Crate) -> Option<ast::NodeId> {
 40      let mut ctx = MacroRegistrarContext { registrars: Vec::new() };
 41      visit::walk_crate(&mut ctx, krate, ());
 42  
 43      match ctx.registrars.len() {
 44          0 => None,
 45          1 => {
 46              let (node_id, _) = ctx.registrars.pop().unwrap();
 47              Some(node_id)
 48          },
 49          _ => {
 50              diagnostic.handler().err("multiple macro registration functions found");
 51              for &(_, span) in ctx.registrars.iter() {
 52                  diagnostic.span_note(span, "one is here");
 53              }
 54              diagnostic.handler().abort_if_errors();
 55              unreachable!();
 56          }
 57      }
 58  }