diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 98fd37d7633cf..6bccf7268bb48 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -36,6 +36,7 @@ use std::vec; use syntax::ast; use syntax::ast_map::{path, path_mod, path_name}; use syntax::attr; +use syntax::attr::{AttrMetaMethods}; use syntax::print::pprust; use syntax::parse::token; @@ -502,7 +503,7 @@ pub fn build_link_meta(sess: Session, struct ProvidedMetas { name: Option<@str>, vers: Option<@str>, - cmh_items: ~[@ast::meta_item] + cmh_items: ~[@ast::MetaItem] } fn provided_link_metas(sess: Session, c: &ast::crate) -> @@ -513,18 +514,10 @@ pub fn build_link_meta(sess: Session, let linkage_metas = attr::find_linkage_metas(c.node.attrs); attr::require_unique_names(sess.diagnostic(), linkage_metas); for linkage_metas.iter().advance |meta| { - match attr::get_meta_item_value_str(*meta) { - Some(value) => { - let item_name : &str = attr::get_meta_item_name(*meta); - match item_name { - // Changing attr would avoid the need for the copy - // here - "name" => name = Some(value), - "vers" => vers = Some(value), - _ => cmh_items.push(*meta) - } - }, - None => cmh_items.push(*meta) + match meta.name_str_pair() { + Some((n, value)) if "name" == n => name = Some(value), + Some((n, value)) if "vers" == n => vers = Some(value), + _ => cmh_items.push(*meta) } } @@ -537,7 +530,7 @@ pub fn build_link_meta(sess: Session, // This calculates CMH as defined above fn crate_meta_extras_hash(symbol_hasher: &mut hash::State, - cmh_items: ~[@ast::meta_item], + cmh_items: ~[@ast::MetaItem], dep_hashes: ~[@str]) -> @str { fn len_and_str(s: &str) -> ~str { fmt!("%u_%s", s.len(), s) @@ -549,16 +542,16 @@ pub fn build_link_meta(sess: Session, let cmh_items = attr::sort_meta_items(cmh_items); - fn hash(symbol_hasher: &mut hash::State, m: &@ast::meta_item) { + fn hash(symbol_hasher: &mut hash::State, m: &@ast::MetaItem) { match m.node { - ast::meta_name_value(key, value) => { + ast::MetaNameValue(key, value) => { write_string(symbol_hasher, len_and_str(key)); write_string(symbol_hasher, len_and_str_lit(value)); } - ast::meta_word(name) => { + ast::MetaWord(name) => { write_string(symbol_hasher, len_and_str(name)); } - ast::meta_list(name, ref mis) => { + ast::MetaList(name, ref mis) => { write_string(symbol_hasher, len_and_str(name)); for mis.iter().advance |m_| { hash(symbol_hasher, m_); diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index e85b3239e8055..796e6213921c2 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -34,6 +34,7 @@ use extra::getopts; use syntax::ast; use syntax::abi; use syntax::attr; +use syntax::attr::{AttrMetaMethods}; use syntax::codemap; use syntax::diagnostic; use syntax::parse; @@ -95,12 +96,9 @@ pub fn default_configuration(sess: Session, argv0: @str, input: &input) -> mk(@"build_input", source_name(input))]; } -pub fn append_configuration(cfg: ast::crate_cfg, name: @str) - -> ast::crate_cfg { - if attr::contains_name(cfg, name) { - cfg - } else { - vec::append_one(cfg, attr::mk_word_item(name)) +pub fn append_configuration(cfg: &mut ast::crate_cfg, name: @str) { + if !cfg.iter().any(|mi| mi.name() == name) { + cfg.push(attr::mk_word_item(name)) } } @@ -109,18 +107,11 @@ pub fn build_configuration(sess: Session, argv0: @str, input: &input) -> // Combine the configuration requested by the session (command line) with // some default and generated configuration items let default_cfg = default_configuration(sess, argv0, input); - let user_cfg = sess.opts.cfg.clone(); + let mut user_cfg = sess.opts.cfg.clone(); // If the user wants a test runner, then add the test cfg - let user_cfg = if sess.opts.test { - append_configuration(user_cfg, @"test") - } else { - user_cfg - }; - + if sess.opts.test { append_configuration(&mut user_cfg, @"test") } // If the user requested GC, then add the GC cfg - let user_cfg = append_configuration( - user_cfg, - if sess.opts.gc { @"gc" } else { @"nogc" }); + append_configuration(&mut user_cfg, if sess.opts.gc { @"gc" } else { @"nogc" }); return vec::append(user_cfg, default_cfg); } @@ -130,7 +121,7 @@ fn parse_cfgspecs(cfgspecs: ~[~str], do cfgspecs.consume_iter().transform |s| { let sess = parse::new_parse_sess(Some(demitter)); parse::parse_meta_from_source_str(@"cfgspec", s.to_managed(), ~[], sess) - }.collect() + }.collect::() } pub enum input { @@ -215,6 +206,7 @@ pub fn compile_rest(sess: Session, crate = time(time_passes, ~"configuration 2", || front::config::strip_unconfigured_items(crate)); + crate = time(time_passes, ~"maybe building test harness", || front::test::modify_for_testing(sess, crate)); } @@ -870,7 +862,7 @@ pub struct OutputFilenames { pub fn build_output_filenames(input: &input, odir: &Option, ofile: &Option, - attrs: &[ast::attribute], + attrs: &[ast::Attribute], sess: Session) -> @OutputFilenames { let obj_path; @@ -912,12 +904,10 @@ pub fn build_output_filenames(input: &input, let linkage_metas = attr::find_linkage_metas(attrs); if !linkage_metas.is_empty() { // But if a linkage meta is present, that overrides - let maybe_matches = attr::find_meta_items_by_name(linkage_metas, "name"); - if !maybe_matches.is_empty() { - match attr::get_meta_item_value_str(maybe_matches[0]) { - Some(s) => stem = s, - _ => () - } + let maybe_name = linkage_metas.iter().find_(|m| "name" == m.name()); + match maybe_name.chain(|m| m.value_str()) { + Some(s) => stem = s, + _ => () } // If the name is missing, we just default to the filename // version @@ -1011,7 +1001,8 @@ mod test { @"rustc", matches, diagnostic::emit); let sess = build_session(sessopts, diagnostic::emit); let cfg = build_configuration(sess, @"whatever", &str_input(@"")); - let test_items = attr::find_meta_items_by_name(cfg, "test"); - assert_eq!(test_items.len(), 1u); + let mut test_items = cfg.iter().filter(|m| "test" == m.name()); + assert!(test_items.next().is_some()); + assert!(test_items.next().is_none()); } } diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 7579616b4ce1d..6bdab3ad7150d 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -369,7 +369,7 @@ pub fn building_library(req_crate_type: crate_type, match syntax::attr::first_attr_value_str_by_name( crate.node.attrs, "crate_type") { - Some(s) if "lib" == s => true, + Some(s) => "lib" == s, _ => false } } @@ -395,18 +395,11 @@ mod test { use driver::session::{unknown_crate}; use syntax::ast; + use syntax::attr; use syntax::codemap; - fn make_crate_type_attr(t: @str) -> ast::attribute { - codemap::respan(codemap::dummy_sp(), ast::attribute_ { - style: ast::attr_outer, - value: @codemap::respan(codemap::dummy_sp(), - ast::meta_name_value( - @"crate_type", - codemap::respan(codemap::dummy_sp(), - ast::lit_str(t)))), - is_sugared_doc: false - }) + fn make_crate_type_attr(t: @str) -> ast::Attribute { + attr::mk_attr(attr::mk_name_value_item_str(@"crate_type", t)) } fn make_crate(with_bin: bool, with_lib: bool) -> @ast::crate { diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 8852478119178..c8049ef8cfd1e 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -12,7 +12,7 @@ use std::option; use syntax::{ast, fold, attr}; -type in_cfg_pred = @fn(attrs: &[ast::attribute]) -> bool; +type in_cfg_pred = @fn(attrs: &[ast::Attribute]) -> bool; struct Context { in_cfg: in_cfg_pred @@ -175,31 +175,6 @@ fn trait_method_in_cfg(cx: @Context, meth: &ast::trait_method) -> bool { // Determine if an item should be translated in the current crate // configuration based on the item's attributes -fn in_cfg(cfg: &[@ast::meta_item], attrs: &[ast::attribute]) -> bool { - metas_in_cfg(cfg, attr::attr_metas(attrs)) -} - -pub fn metas_in_cfg(cfg: &[@ast::meta_item], - metas: &[@ast::meta_item]) -> bool { - // The "cfg" attributes on the item - let cfg_metas = attr::find_meta_items_by_name(metas, "cfg"); - - // Pull the inner meta_items from the #[cfg(meta_item, ...)] attributes, - // so we can match against them. This is the list of configurations for - // which the item is valid - let cfg_metas = cfg_metas.consume_iter() - .filter_map(|i| attr::get_meta_item_list(i)) - .collect::<~[~[@ast::meta_item]]>(); - - if cfg_metas.iter().all(|c| c.is_empty()) { return true; } - - cfg_metas.iter().any(|cfg_meta| { - cfg_meta.iter().all(|cfg_mi| { - match cfg_mi.node { - ast::meta_list(s, ref it) if "not" == s - => it.iter().all(|mi| !attr::contains(cfg, *mi)), - _ => attr::contains(cfg, *cfg_mi) - } - }) - }) +fn in_cfg(cfg: &[@ast::MetaItem], attrs: &[ast::Attribute]) -> bool { + attr::test_cfg(cfg, attrs.iter().transform(|x| *x)) } diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 6865428cd69a7..7ddba6ec7b20f 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -30,10 +30,10 @@ pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::crate) } fn use_std(crate: &ast::crate) -> bool { - !attr::attrs_contains_name(crate.node.attrs, "no_std") + !attr::contains_name(crate.node.attrs, "no_std") } -fn no_prelude(attrs: &[ast::attribute]) -> bool { - attr::attrs_contains_name(attrs, "no_implicit_prelude") +fn no_prelude(attrs: &[ast::Attribute]) -> bool { + attr::contains_name(attrs, "no_implicit_prelude") } fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate { @@ -48,14 +48,8 @@ fn inject_libstd_ref(sess: Session, crate: &ast::crate) -> @ast::crate { node: ast::view_item_extern_mod( sess.ident_of("std"), ~[], n1), attrs: ~[ - spanned(ast::attribute_ { - style: ast::attr_inner, - value: @spanned(ast::meta_name_value( - @"vers", - spanned(ast::lit_str(STD_VERSION.to_managed())) - )), - is_sugared_doc: false - }) + attr::mk_attr( + attr::mk_name_value_item_str(@"vers", STD_VERSION.to_managed())) ], vis: ast::private, span: dummy_sp() diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index e83c5ff6d1095..020ad731d5a71 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -23,6 +23,7 @@ use syntax::ext::base::ExtCtxt; use syntax::fold; use syntax::print::pprust; use syntax::{ast, ast_util}; +use syntax::attr::AttrMetaMethods; type node_id_gen = @fn() -> ast::node_id; @@ -50,8 +51,7 @@ pub fn modify_for_testing(sess: session::Session, // We generate the test harness when building in the 'test' // configuration, either with the '--test' or '--cfg test' // command line options. - let should_test = attr::contains(crate.node.config, - attr::mk_word_item(@"test")); + let should_test = attr::contains_name(crate.node.config, "test"); if should_test { generate_test_harness(sess, crate) @@ -95,8 +95,8 @@ fn strip_test_functions(crate: &ast::crate) -> @ast::crate { // When not compiling with --test we should not compile the // #[test] functions do config::strip_items(crate) |attrs| { - !attr::contains_name(attr::attr_metas(attrs), "test") && - !attr::contains_name(attr::attr_metas(attrs), "bench") + !attr::contains_name(attrs, "test") && + !attr::contains_name(attrs, "bench") } } @@ -111,7 +111,7 @@ fn fold_mod(cx: @mut TestCtxt, if !*cx.sess.building_library { @ast::item { attrs: do item.attrs.iter().filter_map |attr| { - if "main" != attr::get_attr_name(attr) { + if "main" != attr.name() { Some(*attr) } else { None @@ -180,8 +180,7 @@ fn fold_item(cx: @mut TestCtxt, i: @ast::item, fld: @fold::ast_fold) } fn is_test_fn(cx: @mut TestCtxt, i: @ast::item) -> bool { - let has_test_attr = !attr::find_attrs_by_name(i.attrs, - "test").is_empty(); + let has_test_attr = attr::contains_name(i.attrs, "test"); fn has_test_signature(i: @ast::item) -> bool { match &i.node { @@ -205,11 +204,12 @@ fn is_test_fn(cx: @mut TestCtxt, i: @ast::item) -> bool { "functions used as tests must have signature fn() -> ()." ); } + return has_test_attr && has_test_signature(i); } fn is_bench_fn(i: @ast::item) -> bool { - let has_bench_attr = !attr::find_attrs_by_name(i.attrs, "bench").is_empty(); + let has_bench_attr = attr::contains_name(i.attrs, "bench"); fn has_test_signature(i: @ast::item) -> bool { match i.node { @@ -233,21 +233,17 @@ fn is_bench_fn(i: @ast::item) -> bool { } fn is_ignored(cx: @mut TestCtxt, i: @ast::item) -> bool { - let ignoreattrs = attr::find_attrs_by_name(i.attrs, "ignore"); - let ignoreitems = attr::attr_metas(ignoreattrs); - return if !ignoreitems.is_empty() { - let cfg_metas = ignoreitems.consume_iter() - .filter_map(|i| attr::get_meta_item_list(i)) - .collect::<~[~[@ast::meta_item]]>() - .concat_vec(); - config::metas_in_cfg(cx.crate.node.config.clone(), cfg_metas) - } else { - false + do i.attrs.iter().any |attr| { + // check ignore(cfg(foo, bar)) + "ignore" == attr.name() && match attr.meta_item_list() { + Some(ref cfgs) => attr::test_cfg(cx.crate.node.config, cfgs.iter().transform(|x| *x)), + None => true + } } } fn should_fail(i: @ast::item) -> bool { - !attr::find_attrs_by_name(i.attrs, "should_fail").is_empty() + attr::contains_name(i.attrs, "should_fail") } fn add_test_module(cx: &TestCtxt, m: &ast::_mod) -> ast::_mod { @@ -278,19 +274,15 @@ mod __test { */ fn mk_std(cx: &TestCtxt) -> ast::view_item { - let vers = ast::lit_str(@"0.8-pre"); - let vers = nospan(vers); - let mi = ast::meta_name_value(@"vers", vers); - let mi = nospan(mi); - let id_std = cx.sess.ident_of("extra"); - let vi = if is_std(cx) { + let id_extra = cx.sess.ident_of("extra"); + let vi = if is_extra(cx) { ast::view_item_use( - ~[@nospan(ast::view_path_simple(id_std, - path_node(~[id_std]), + ~[@nospan(ast::view_path_simple(id_extra, + path_node(~[id_extra]), cx.sess.next_node_id()))]) } else { - ast::view_item_extern_mod(id_std, ~[@mi], - cx.sess.next_node_id()) + let mi = attr::mk_name_value_item_str(@"vers", @"0.8-pre"); + ast::view_item_extern_mod(id_extra, ~[mi], cx.sess.next_node_id()) }; ast::view_item { node: vi, @@ -377,15 +369,12 @@ fn mk_tests(cx: &TestCtxt) -> @ast::item { )).get() } -fn is_std(cx: &TestCtxt) -> bool { - let is_std = { - let items = attr::find_linkage_metas(cx.crate.node.attrs); - match attr::last_meta_item_value_str_by_name(items, "name") { - Some(s) if "extra" == s => true, - _ => false - } - }; - return is_std; +fn is_extra(cx: &TestCtxt) -> bool { + let items = attr::find_linkage_metas(cx.crate.node.attrs); + match attr::last_meta_item_value_str_by_name(items, "name") { + Some(s) if "extra" == s => true, + _ => false + } } fn mk_test_descs(cx: &TestCtxt) -> @ast::expr { diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index dea263532b286..16b5ecad5b7c8 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -18,6 +18,7 @@ use metadata::loader; use std::hashmap::HashMap; use syntax::attr; +use syntax::attr::AttrMetaMethods; use syntax::codemap::{span, dummy_sp}; use syntax::diagnostic::span_handler; use syntax::parse::token; @@ -59,7 +60,7 @@ struct cache_entry { cnum: int, span: span, hash: @str, - metas: @~[@ast::meta_item] + metas: @~[@ast::MetaItem] } fn dump_crates(crate_cache: &[cache_entry]) { @@ -123,10 +124,9 @@ struct Env { fn visit_crate(e: &Env, c: &ast::crate) { let cstore = e.cstore; - let link_args = attr::find_attrs_by_name(c.node.attrs, "link_args"); - for link_args.iter().advance |a| { - match attr::get_meta_item_value_str(attr::attr_meta(*a)) { + for c.node.attrs.iter().filter(|m| "link_args" == m.name()).advance |a| { + match a.value_str() { Some(ref linkarg) => { cstore::add_used_link_args(cstore, *linkarg); } @@ -160,13 +160,17 @@ fn visit_item(e: &Env, i: @ast::item) { let cstore = e.cstore; let mut already_added = false; - let link_args = attr::find_attrs_by_name(i.attrs, "link_args"); + let link_args = i.attrs.iter() + .filter_map(|at| if "link_args" == at.name() {Some(at)} else {None}) + .collect::<~[&ast::Attribute]>(); match fm.sort { ast::named => { - let foreign_name = - match attr::first_attr_value_str_by_name(i.attrs, - "link_name") { + let link_name = i.attrs.iter() + .find_(|at| "link_name" == at.name()) + .chain(|at| at.value_str()); + + let foreign_name = match link_name { Some(nn) => { if nn.is_empty() { e.diag.span_fatal( @@ -178,7 +182,7 @@ fn visit_item(e: &Env, i: @ast::item) { } None => token::ident_to_str(&i.ident) }; - if attr::find_attrs_by_name(i.attrs, "nolink").is_empty() { + if !attr::contains_name(i.attrs, "nolink") { already_added = !cstore::add_used_library(cstore, foreign_name); } @@ -190,8 +194,8 @@ fn visit_item(e: &Env, i: @ast::item) { ast::anonymous => { /* do nothing */ } } - for link_args.iter().advance |a| { - match attr::get_meta_item_value_str(attr::attr_meta(*a)) { + for link_args.iter().advance |m| { + match m.value_str() { Some(linkarg) => { cstore::add_used_link_args(cstore, linkarg); } @@ -203,21 +207,21 @@ fn visit_item(e: &Env, i: @ast::item) { } } -fn metas_with(ident: @str, key: @str, mut metas: ~[@ast::meta_item]) - -> ~[@ast::meta_item] { - let name_items = attr::find_meta_items_by_name(metas, key); - if name_items.is_empty() { +fn metas_with(ident: @str, key: @str, mut metas: ~[@ast::MetaItem]) + -> ~[@ast::MetaItem] { + // Check if key isn't there yet. + if !attr::contains_name(metas, key) { metas.push(attr::mk_name_value_item_str(key, ident)); } metas } -fn metas_with_ident(ident: @str, metas: ~[@ast::meta_item]) - -> ~[@ast::meta_item] { +fn metas_with_ident(ident: @str, metas: ~[@ast::MetaItem]) + -> ~[@ast::MetaItem] { metas_with(ident, @"name", metas) } -fn existing_match(e: &Env, metas: &[@ast::meta_item], hash: &str) +fn existing_match(e: &Env, metas: &[@ast::MetaItem], hash: &str) -> Option { for e.crate_cache.iter().advance |c| { if loader::metadata_matches(*c.metas, metas) @@ -230,7 +234,7 @@ fn existing_match(e: &Env, metas: &[@ast::meta_item], hash: &str) fn resolve_crate(e: @mut Env, ident: ast::ident, - metas: ~[@ast::meta_item], + metas: ~[@ast::MetaItem], hash: @str, span: span) -> ast::crate_num { diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index f336b0f4e4c5e..2fc4ba8a1bd4d 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -151,7 +151,7 @@ pub fn get_static_methods_if_impl(cstore: @mut cstore::CStore, pub fn get_item_attrs(cstore: @mut cstore::CStore, def_id: ast::def_id, - f: &fn(~[@ast::meta_item])) { + f: &fn(~[@ast::MetaItem])) { let cdata = cstore::get_crate_data(cstore, def_id.crate); decoder::get_item_attrs(cdata, def_id.node, f) } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index caa170605dec3..f8c6c6288ac04 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -966,7 +966,7 @@ pub fn get_static_methods_if_impl(intr: @ident_interner, pub fn get_item_attrs(cdata: cmd, node_id: ast::node_id, - f: &fn(~[@ast::meta_item])) { + f: &fn(~[@ast::MetaItem])) { let item = lookup_item(node_id, cdata.data); for reader::tagged_docs(item, tag_attributes) |attributes| { @@ -1073,8 +1073,8 @@ fn item_family_to_str(fam: Family) -> ~str { } } -fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] { - let mut items: ~[@ast::meta_item] = ~[]; +fn get_meta_items(md: ebml::Doc) -> ~[@ast::MetaItem] { + let mut items: ~[@ast::MetaItem] = ~[]; for reader::tagged_docs(md, tag_meta_item_word) |meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); let n = nd.as_str_slice().to_managed(); @@ -1085,7 +1085,7 @@ fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] { let vd = reader::get_doc(meta_item_doc, tag_meta_item_value); let n = nd.as_str_slice().to_managed(); let v = vd.as_str_slice().to_managed(); - // FIXME (#623): Should be able to decode meta_name_value variants, + // FIXME (#623): Should be able to decode MetaNameValue variants, // but currently the encoder just drops them items.push(attr::mk_name_value_item_str(n, v)); }; @@ -1098,8 +1098,8 @@ fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] { return items; } -fn get_attributes(md: ebml::Doc) -> ~[ast::attribute] { - let mut attrs: ~[ast::attribute] = ~[]; +fn get_attributes(md: ebml::Doc) -> ~[ast::Attribute] { + let mut attrs: ~[ast::Attribute] = ~[]; match reader::maybe_get_doc(md, tag_attributes) { option::Some(attrs_d) => { for reader::tagged_docs(attrs_d, tag_attribute) |attr_doc| { @@ -1110,8 +1110,8 @@ fn get_attributes(md: ebml::Doc) -> ~[ast::attribute] { let meta_item = meta_items[0]; attrs.push( codemap::spanned { - node: ast::attribute_ { - style: ast::attr_outer, + node: ast::Attribute_ { + style: ast::AttrOuter, value: meta_item, is_sugared_doc: false, }, @@ -1145,7 +1145,7 @@ fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: &str, out.write_str("\n\n"); } -pub fn get_crate_attributes(data: @~[u8]) -> ~[ast::attribute] { +pub fn get_crate_attributes(data: @~[u8]) -> ~[ast::Attribute] { return get_attributes(reader::Doc(data)); } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index ab42e84e2acfe..86c470b09edc5 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -36,6 +36,7 @@ use syntax::ast; use syntax::ast_map; use syntax::ast_util::*; use syntax::attr; +use syntax::attr::AttrMetaMethods; use syntax::diagnostic::span_handler; use syntax::opt_vec::OptVec; use syntax::opt_vec; @@ -821,10 +822,11 @@ fn purity_static_method_family(p: purity) -> char { } -fn should_inline(attrs: &[attribute]) -> bool { - match attr::find_inline_attr(attrs) { - attr::ia_none | attr::ia_never => false, - attr::ia_hint | attr::ia_always => true +fn should_inline(attrs: &[Attribute]) -> bool { + use syntax::attr::*; + match find_inline_attr(attrs) { + InlineNone | InlineNever => false, + InlineHint | InlineAlways => true } } @@ -1313,16 +1315,16 @@ fn write_int(writer: @io::Writer, &n: &int) { writer.write_be_u32(n as u32); } -fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @meta_item) { +fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @MetaItem) { match mi.node { - meta_word(name) => { + MetaWord(name) => { ebml_w.start_tag(tag_meta_item_word); ebml_w.start_tag(tag_meta_item_name); ebml_w.writer.write(name.as_bytes()); ebml_w.end_tag(); ebml_w.end_tag(); } - meta_name_value(name, value) => { + MetaNameValue(name, value) => { match value.node { lit_str(value) => { ebml_w.start_tag(tag_meta_item_name_value); @@ -1337,7 +1339,7 @@ fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @meta_item) { _ => {/* FIXME (#623): encode other variants */ } } } - meta_list(name, ref items) => { + MetaList(name, ref items) => { ebml_w.start_tag(tag_meta_item_list); ebml_w.start_tag(tag_meta_item_name); ebml_w.writer.write(name.as_bytes()); @@ -1350,7 +1352,7 @@ fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @meta_item) { } } -fn encode_attributes(ebml_w: &mut writer::Encoder, attrs: &[attribute]) { +fn encode_attributes(ebml_w: &mut writer::Encoder, attrs: &[Attribute]) { ebml_w.start_tag(tag_attributes); for attrs.iter().advance |attr| { ebml_w.start_tag(tag_attribute); @@ -1365,10 +1367,10 @@ fn encode_attributes(ebml_w: &mut writer::Encoder, attrs: &[attribute]) { // 'name' and 'vers' items, so if the user didn't provide them we will throw // them in anyway with default values. fn synthesize_crate_attrs(ecx: &EncodeContext, - crate: &crate) -> ~[attribute] { + crate: &crate) -> ~[Attribute] { - fn synthesize_link_attr(ecx: &EncodeContext, items: ~[@meta_item]) -> - attribute { + fn synthesize_link_attr(ecx: &EncodeContext, items: ~[@MetaItem]) -> + Attribute { assert!(!ecx.link_meta.name.is_empty()); assert!(!ecx.link_meta.vers.is_empty()); @@ -1380,29 +1382,29 @@ fn synthesize_crate_attrs(ecx: &EncodeContext, attr::mk_name_value_item_str(@"vers", ecx.link_meta.vers); - let other_items = - { - let tmp = attr::remove_meta_items_by_name(items, "name"); - attr::remove_meta_items_by_name(tmp, "vers") - }; + let mut meta_items = ~[name_item, vers_item]; - let meta_items = vec::append(~[name_item, vers_item], other_items); + for items.iter() + .filter(|mi| "name" != mi.name() && "vers" != mi.name()) + .advance |&mi| { + meta_items.push(mi); + } let link_item = attr::mk_list_item(@"link", meta_items); return attr::mk_attr(link_item); } - let mut attrs: ~[attribute] = ~[]; + let mut attrs = ~[]; let mut found_link_attr = false; for crate.node.attrs.iter().advance |attr| { attrs.push( - if "link" != attr::get_attr_name(attr) { + if "link" != attr.name() { *attr } else { - match attr.node.value.node { - meta_list(_, ref l) => { + match attr.meta_item_list() { + Some(l) => { found_link_attr = true;; - synthesize_link_attr(ecx, (*l).clone()) + synthesize_link_attr(ecx, l.to_owned()) } _ => *attr } diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 5cf69e26a5019..d6687b4313a25 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -22,6 +22,7 @@ use syntax::parse::token; use syntax::parse::token::ident_interner; use syntax::print::pprust; use syntax::{ast, attr}; +use syntax::attr::AttrMetaMethods; use std::cast; use std::io; @@ -46,7 +47,7 @@ pub struct Context { filesearch: @FileSearch, span: span, ident: ast::ident, - metas: ~[@ast::meta_item], + metas: ~[@ast::MetaItem], hash: @str, os: os, is_static: bool, @@ -55,7 +56,7 @@ pub struct Context { pub fn load_library_crate(cx: &Context) -> (~str, @~[u8]) { match find_library_crate(cx) { - Some(ref t) => return (/*bad*/(*t).clone()), + Some(t) => t, None => { cx.diag.span_fatal(cx.span, fmt!("can't find crate for `%s`", @@ -140,15 +141,11 @@ fn find_library_crate_aux( } } -pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @str { +pub fn crate_name_from_metas(metas: &[@ast::MetaItem]) -> @str { for metas.iter().advance |m| { - match m.node { - ast::meta_name_value(s, ref l) if s == @"name" => - match l.node { - ast::lit_str(s) => return s, - _ => () - }, - _ => () + match m.name_str_pair() { + Some((name, s)) if "name" == name => { return s; } + _ => {} } } fail!("expected to find the crate name") @@ -156,7 +153,7 @@ pub fn crate_name_from_metas(metas: &[@ast::meta_item]) -> @str { pub fn note_linkage_attrs(intr: @ident_interner, diag: @span_handler, - attrs: ~[ast::attribute]) { + attrs: ~[ast::Attribute]) { let r = attr::find_linkage_metas(attrs); for r.iter().advance |mi| { diag.handler().note(fmt!("meta: %s", pprust::meta_item_to_str(*mi,intr))); @@ -164,7 +161,7 @@ pub fn note_linkage_attrs(intr: @ident_interner, } fn crate_matches(crate_data: @~[u8], - metas: &[@ast::meta_item], + metas: &[@ast::MetaItem], hash: @str) -> bool { let attrs = decoder::get_crate_attributes(crate_data); let linkage_metas = attr::find_linkage_metas(attrs); @@ -175,18 +172,15 @@ fn crate_matches(crate_data: @~[u8], metadata_matches(linkage_metas, metas) } -pub fn metadata_matches(extern_metas: &[@ast::meta_item], - local_metas: &[@ast::meta_item]) -> bool { +pub fn metadata_matches(extern_metas: &[@ast::MetaItem], + local_metas: &[@ast::MetaItem]) -> bool { debug!("matching %u metadata requirements against %u items", local_metas.len(), extern_metas.len()); - for local_metas.iter().advance |needed| { - if !attr::contains(extern_metas, *needed) { - return false; - } + do local_metas.iter().all |needed| { + attr::contains(extern_metas, *needed) } - return true; } fn get_metadata_section(os: os, diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 9bcfab0773fff..6f23f94b25e08 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -13,9 +13,9 @@ use driver::session; use driver::session::Session; use syntax::parse::token::special_idents; use syntax::ast::{crate, node_id, item, item_fn}; +use syntax::attr; use syntax::codemap::span; use syntax::visit::{default_visitor, mk_vt, vt, Visitor, visit_crate, visit_item}; -use syntax::attr::{attrs_contains_name}; use syntax::ast_map; use std::util; @@ -90,7 +90,7 @@ fn find_item(item: @item, ctxt: @mut EntryContext, visitor: EntryVisitor) { } } - if attrs_contains_name(item.attrs, "main") { + if attr::contains_name(item.attrs, "main") { if ctxt.attr_main_fn.is_none() { ctxt.attr_main_fn = Some((item.id, item.span)); } else { @@ -100,7 +100,7 @@ fn find_item(item: @item, ctxt: @mut EntryContext, visitor: EntryVisitor) { } } - if attrs_contains_name(item.attrs, "start") { + if attr::contains_name(item.attrs, "start") { if ctxt.start_fn.is_none() { ctxt.start_fn = Some((item.id, item.span)); } else { diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index deafe85a2c94a..b19b7652a9147 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -17,7 +17,7 @@ use util::ppaux::{Repr, ty_to_str}; use util::ppaux::UserString; use syntax::ast::*; -use syntax::attr::attrs_contains_name; +use syntax::attr; use syntax::codemap::span; use syntax::print::pprust::expr_to_str; use syntax::{visit, ast_util}; @@ -113,7 +113,7 @@ fn check_block(block: &blk, (cx, visitor): (Context, visit::vt)) { fn check_item(item: @item, (cx, visitor): (Context, visit::vt)) { // If this is a destructor, check kinds. - if !attrs_contains_name(item.attrs, "unsafe_destructor") { + if !attr::contains_name(item.attrs, "unsafe_destructor") { match item.node { item_impl(_, Some(ref trait_ref), ref self_type, _) => { match cx.tcx.def_map.find(&trait_ref.ref_id) { @@ -574,4 +574,3 @@ pub fn check_cast_for_escaping_regions( cx.tcx.region_maps.is_subregion_of(r_sub, r_sup) } } - diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index a49e50d5c38d7..da557c07906f0 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -23,9 +23,9 @@ use driver::session::Session; use metadata::csearch::each_lang_item; use metadata::cstore::iter_crate_data; -use syntax::ast::{crate, def_id, lit_str, meta_item}; -use syntax::ast::{meta_list, meta_name_value, meta_word}; +use syntax::ast::{crate, def_id, MetaItem}; use syntax::ast_util::local_def; +use syntax::attr::AttrMetaMethods; use syntax::visit::{default_simple_visitor, mk_simple_visitor, SimpleVisitor}; use syntax::visit::visit_crate; @@ -360,17 +360,12 @@ impl<'self> LanguageItemCollector<'self> { pub fn match_and_collect_meta_item(&mut self, item_def_id: def_id, - meta_item: &meta_item) { - match meta_item.node { - meta_name_value(key, literal) => { - match literal.node { - lit_str(value) => { - self.match_and_collect_item(item_def_id, key, value); - } - _ => {} // Skip. - } + meta_item: &MetaItem) { + match meta_item.name_str_pair() { + Some((key, value)) => { + self.match_and_collect_item(item_def_id, key, value); } - meta_word(*) | meta_list(*) => {} // Skip. + None => {} // skip } } diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 486939be58d4c..2e6696e02fc50 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -26,6 +26,7 @@ use std::u64; use std::u8; use extra::smallintmap::SmallIntMap; use syntax::attr; +use syntax::attr::AttrMetaMethods; use syntax::codemap::span; use syntax::codemap; use syntax::{ast, visit, ast_util}; @@ -417,7 +418,7 @@ impl Context { * current lint context, call the provided function, then reset the * lints in effect to their previous state. */ - fn with_lint_attrs(@mut self, attrs: &[ast::attribute], f: &fn()) { + fn with_lint_attrs(@mut self, attrs: &[ast::Attribute], f: &fn()) { // Parse all of the lint attributes, and then add them all to the // current dictionary of lint information. Along the way, keep a history // of what we changed so we can roll everything back after invoking the @@ -454,18 +455,14 @@ impl Context { } // detect doc(hidden) - let mut doc_hidden = false; - let r = attr::find_attrs_by_name(attrs, "doc"); - for r.iter().advance |attr| { - match attr::get_meta_item_list(attr.node.value) { - Some(s) => { - if attr::find_meta_items_by_name(s, "hidden").len() > 0 { - doc_hidden = true; - } + let mut doc_hidden = do attrs.iter().any |attr| { + "doc" == attr.name() && + match attr.meta_item_list() { + Some(l) => attr::contains_name(l, "hidden"), + None => false // not of the form #[doc(...)] } - None => {} - } - } + }; + if doc_hidden && !self.doc_hidden { self.doc_hidden = true; } else { @@ -517,16 +514,15 @@ impl Context { } pub fn each_lint(sess: session::Session, - attrs: &[ast::attribute], - f: &fn(@ast::meta_item, level, @str) -> bool) -> bool { + attrs: &[ast::Attribute], + f: &fn(@ast::MetaItem, level, @str) -> bool) -> bool { let xs = [allow, warn, deny, forbid]; for xs.iter().advance |&level| { let level_name = level_to_str(level); - let attrs = attr::find_attrs_by_name(attrs, level_name); - for attrs.iter().advance |attr| { + for attrs.iter().filter(|m| level_name == m.name()).advance |attr| { let meta = attr.node.value; let metas = match meta.node { - ast::meta_list(_, ref metas) => metas, + ast::MetaList(_, ref metas) => metas, _ => { sess.span_err(meta.span, "malformed lint attribute"); loop; @@ -534,7 +530,7 @@ pub fn each_lint(sess: session::Session, }; for metas.iter().advance |meta| { match meta.node { - ast::meta_word(lintname) => { + ast::MetaWord(lintname) => { if !f(*meta, level, lintname) { return false; } @@ -1035,7 +1031,7 @@ fn lint_unnecessary_allocations() -> visit::vt<@mut Context> { } fn lint_missing_doc() -> visit::vt<@mut Context> { - fn check_attrs(cx: @mut Context, attrs: &[ast::attribute], + fn check_attrs(cx: @mut Context, attrs: &[ast::Attribute], sp: span, msg: &str) { // If we're building a test harness, then warning about documentation is // probably not really relevant right now diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 036c075148343..69c5392f002f1 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -376,8 +376,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, visit_item: |item, (method_map, visitor)| { // Do not check privacy inside items with the resolve_unexported // attribute. This is used for the test runner. - if !attr::contains_name(attr::attr_metas(item.attrs), - "!resolve_unexported") { + if !attr::contains_name(item.attrs, "!resolve_unexported") { visit::visit_item(item, (method_map, visitor)); } }, diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index a0ba9ac5a8841..d11ac758f6e9a 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -31,8 +31,8 @@ use syntax::visit; // Returns true if the given set of attributes contains the `#[inline]` // attribute. -fn attributes_specify_inlining(attrs: &[attribute]) -> bool { - attr::attrs_contains_name(attrs, "inline") +fn attributes_specify_inlining(attrs: &[Attribute]) -> bool { + attr::contains_name(attrs, "inline") } // Returns true if the given set of generics implies that the item it's @@ -431,4 +431,3 @@ pub fn find_reachable(tcx: ty::ctxt, // Return the set of reachable symbols. reachable_context.reachable_symbols } - diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 80078eba23936..fa8390922122f 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -26,7 +26,7 @@ use syntax::ast_util::{def_id_of_def, local_def}; use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method}; use syntax::ast_util::{Privacy, Public, Private}; use syntax::ast_util::{variant_visibility_to_privacy, visibility_to_privacy}; -use syntax::attr::{attr_metas, contains_name}; +use syntax::attr; use syntax::parse::token; use syntax::parse::token::ident_interner; use syntax::parse::token::special_idents; @@ -3494,8 +3494,7 @@ impl Resolver { // Items with the !resolve_unexported attribute are X-ray contexts. // This is used to allow the test runner to run unexported tests. let orig_xray_flag = self.xray_context; - if contains_name(attr_metas(item.attrs), - "!resolve_unexported") { + if attr::contains_name(item.attrs, "!resolve_unexported") { self.xray_context = Xray; } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 588b0b5c75f48..04a016524bd9d 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -79,6 +79,7 @@ use syntax::ast::ident; use syntax::ast_map::{path, path_elt_to_str, path_name}; use syntax::ast_util::{local_def}; use syntax::attr; +use syntax::attr::AttrMetaMethods; use syntax::codemap::span; use syntax::parse::token; use syntax::parse::token::{special_idents}; @@ -464,13 +465,14 @@ pub fn set_inline_hint(f: ValueRef) { } } -pub fn set_inline_hint_if_appr(attrs: &[ast::attribute], +pub fn set_inline_hint_if_appr(attrs: &[ast::Attribute], llfn: ValueRef) { - match attr::find_inline_attr(attrs) { - attr::ia_hint => set_inline_hint(llfn), - attr::ia_always => set_always_inline(llfn), - attr::ia_never => set_no_inline(llfn), - attr::ia_none => { /* fallthrough */ } + use syntax::attr::*; + match find_inline_attr(attrs) { + InlineHint => set_inline_hint(llfn), + InlineAlways => set_always_inline(llfn), + InlineNever => set_no_inline(llfn), + InlineNone => { /* fallthrough */ } } } @@ -1845,7 +1847,7 @@ pub fn trans_closure(ccx: @mut CrateContext, self_arg: self_arg, param_substs: Option<@param_substs>, id: ast::node_id, - attributes: &[ast::attribute], + attributes: &[ast::Attribute], output_type: ty::t, maybe_load_env: &fn(fn_ctxt), finish: &fn(block)) { @@ -1868,7 +1870,7 @@ pub fn trans_closure(ccx: @mut CrateContext, let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs); // Set the fixed stack segment flag if necessary. - if attr::attrs_contains_name(attributes, "fixed_stack_segment") { + if attr::contains_name(attributes, "fixed_stack_segment") { set_no_inline(fcx.llfn); set_fixed_stack_segment(fcx.llfn); } @@ -1926,7 +1928,7 @@ pub fn trans_fn(ccx: @mut CrateContext, self_arg: self_arg, param_substs: Option<@param_substs>, id: ast::node_id, - attrs: &[ast::attribute]) { + attrs: &[ast::Attribute]) { let the_path_str = path_str(ccx.sess, path); let _s = StatRecorder::new(ccx, the_path_str); @@ -2196,23 +2198,17 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) { // Do static_assert checking. It can't really be done much earlier because we need to get // the value of the bool out of LLVM for item.attrs.iter().advance |attr| { - match attr.node.value.node { - ast::meta_word(x) => { - if x.slice(0, x.len()) == "static_assert" { - if m == ast::m_mutbl { - ccx.sess.span_fatal(expr.span, - "cannot have static_assert \ - on a mutable static"); - } - let v = ccx.const_values.get_copy(&item.id); - unsafe { - if !(llvm::LLVMConstIntGetZExtValue(v) as bool) { - ccx.sess.span_fatal(expr.span, "static assertion failed"); - } - } + if "static_assert" == attr.name() { + if m == ast::m_mutbl { + ccx.sess.span_fatal(expr.span, + "cannot have static_assert on a mutable static"); + } + let v = ccx.const_values.get_copy(&item.id); + unsafe { + if !(llvm::LLVMConstIntGetZExtValue(v) as bool) { + ccx.sess.span_fatal(expr.span, "static assertion failed"); } - }, - _ => () + } } } }, @@ -2258,7 +2254,7 @@ pub fn register_fn(ccx: @mut CrateContext, sp: span, path: path, node_id: ast::node_id, - attrs: &[ast::attribute]) + attrs: &[ast::Attribute]) -> ValueRef { let t = ty::node_id_to_type(ccx.tcx, node_id); register_fn_full(ccx, sp, path, node_id, attrs, t) @@ -2268,7 +2264,7 @@ pub fn register_fn_full(ccx: @mut CrateContext, sp: span, path: path, node_id: ast::node_id, - attrs: &[ast::attribute], + attrs: &[ast::Attribute], node_type: ty::t) -> ValueRef { let llfty = type_of_fn_from_ty(ccx, node_type); @@ -2280,7 +2276,7 @@ pub fn register_fn_fuller(ccx: @mut CrateContext, sp: span, path: path, node_id: ast::node_id, - attrs: &[ast::attribute], + attrs: &[ast::Attribute], node_type: ty::t, cc: lib::llvm::CallConv, fn_ty: Type) @@ -2289,7 +2285,7 @@ pub fn register_fn_fuller(ccx: @mut CrateContext, node_id, ast_map::path_to_str(path, token::get_ident_interner())); - let ps = if attr::attrs_contains_name(attrs, "no_mangle") { + let ps = if attr::contains_name(attrs, "no_mangle") { path_elt_to_str(*path.last(), token::get_ident_interner()) } else { mangle_exported_name(ccx, path, node_type) diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index f7d0e71387b4d..355e2f57b2c3f 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -351,10 +351,10 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, cc: lib::llvm::CallConv) { let llwrapfn = get_item_val(ccx, id); let tys = shim_types(ccx, id); - if attr::attrs_contains_name(foreign_item.attrs, "rust_stack") { + if attr::contains_name(foreign_item.attrs, "rust_stack") { build_direct_fn(ccx, llwrapfn, foreign_item, &tys, cc); - } else if attr::attrs_contains_name(foreign_item.attrs, "fast_ffi") { + } else if attr::contains_name(foreign_item.attrs, "fast_ffi") { build_fast_ffi_fn(ccx, llwrapfn, foreign_item, &tys, cc); } else { let llshimfn = build_shim_fn(ccx, foreign_item, &tys, cc); @@ -546,7 +546,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, item: &ast::foreign_item, path: ast_map::path, substs: @param_substs, - attributes: &[ast::attribute], + attributes: &[ast::Attribute], ref_id: Option) { debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident)); @@ -624,7 +624,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, set_always_inline(fcx.llfn); // Set the fixed stack segment flag if necessary. - if attr::attrs_contains_name(attributes, "fixed_stack_segment") { + if attr::contains_name(attributes, "fixed_stack_segment") { set_fixed_stack_segment(fcx.llfn); } @@ -1146,7 +1146,7 @@ pub fn register_foreign_fn(ccx: @mut CrateContext, sp: span, path: ast_map::path, node_id: ast::node_id, - attrs: &[ast::attribute]) + attrs: &[ast::Attribute]) -> ValueRef { let _icx = push_ctxt("foreign::register_foreign_fn"); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 50f331f7e7d48..a2edba7f3d749 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3966,7 +3966,7 @@ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool { &ast_map::node_item(@ast::item { attrs: ref attrs, _ - }, _)) => attr::attrs_contains_name(*attrs, attr), + }, _)) => attr::contains_name(*attrs, attr), _ => tcx.sess.bug(fmt!("has_attr: %? is not an item", did)) } diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs index e61f8d6d74334..f8eff69cc8f3e 100644 --- a/src/librustdoc/attr_parser.rs +++ b/src/librustdoc/attr_parser.rs @@ -18,24 +18,20 @@ an AST's attributes. use syntax::ast; use syntax::attr; +use syntax::attr::{AttrMetaMethods, AttributeMethods}; pub struct CrateAttrs { name: Option<~str> } -fn doc_metas( - attrs: ~[ast::attribute] -) -> ~[@ast::meta_item] { - - let doc_attrs = attr::find_attrs_by_name(attrs, "doc"); - let doc_metas = do doc_attrs.map |attr| { - attr::attr_meta(attr::desugar_doc_attr(attr)) - }; - - return doc_metas; +fn doc_metas(attrs: ~[ast::Attribute]) -> ~[@ast::MetaItem] { + attrs.iter() + .filter(|at| "doc" == at.name()) + .transform(|at| at.desugar_doc().meta()) + .collect() } -pub fn parse_crate(attrs: ~[ast::attribute]) -> CrateAttrs { +pub fn parse_crate(attrs: ~[ast::Attribute]) -> CrateAttrs { let link_metas = attr::find_linkage_metas(attrs); let name = attr::last_meta_item_value_str_by_name(link_metas, "name"); @@ -44,10 +40,10 @@ pub fn parse_crate(attrs: ~[ast::attribute]) -> CrateAttrs { } } -pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> { +pub fn parse_desc(attrs: ~[ast::Attribute]) -> Option<~str> { let doc_strs = do doc_metas(attrs).consume_iter().filter_map |meta| { - attr::get_meta_item_value_str(meta).map(|s| s.to_owned()) - }.collect::<~[~str]>(); + meta.value_str() + }.collect::<~[@str]>(); if doc_strs.is_empty() { None } else { @@ -55,14 +51,11 @@ pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> { } } -pub fn parse_hidden(attrs: ~[ast::attribute]) -> bool { +pub fn parse_hidden(attrs: ~[ast::Attribute]) -> bool { let r = doc_metas(attrs); do r.iter().any |meta| { - match attr::get_meta_item_list(*meta) { - Some(metas) => { - let hiddens = attr::find_meta_items_by_name(metas, "hidden"); - !hiddens.is_empty() - } + match meta.meta_item_list() { + Some(metas) => attr::contains_name(metas, "hidden"), None => false } } @@ -74,7 +67,7 @@ mod test { use syntax; use super::{parse_hidden, parse_crate, parse_desc}; - fn parse_attributes(source: @str) -> ~[ast::attribute] { + fn parse_attributes(source: @str) -> ~[ast::Attribute] { use syntax::parse; use syntax::parse::attr::parser_attr; diff --git a/src/librustdoc/attr_pass.rs b/src/librustdoc/attr_pass.rs index cc274e26f5b2d..697a699915e24 100644 --- a/src/librustdoc/attr_pass.rs +++ b/src/librustdoc/attr_pass.rs @@ -68,7 +68,7 @@ fn fold_crate( doc::CrateDoc { topmod: doc::ModDoc { item: doc::ItemDoc { - name: attrs.name.clone().get_or_default(doc.topmod.name()), + name: attrs.name.clone().get_or_default(doc.topmod.name_()), .. doc.topmod.item.clone() }, .. doc.topmod.clone() @@ -102,7 +102,7 @@ fn fold_item( fn parse_item_attrs( srv: astsrv::Srv, id: doc::AstId, - parse_attrs: ~fn(a: ~[ast::attribute]) -> T) -> T { + parse_attrs: ~fn(a: ~[ast::Attribute]) -> T) -> T { do astsrv::exec(srv) |ctxt| { let attrs = match ctxt.ast_map.get_copy(&id) { ast_map::node_item(item, _) => item.attrs.clone(), @@ -249,7 +249,7 @@ mod test { #[test] fn should_replace_top_module_name_with_crate_name() { let doc = mk_doc(~"#[link(name = \"bond\")];"); - assert!(doc.cratemod().name() == ~"bond"); + assert!(doc.cratemod().name_() == ~"bond"); } #[test] diff --git a/src/librustdoc/doc.rs b/src/librustdoc/doc.rs index 9d173e271eba6..cca898feba2b2 100644 --- a/src/librustdoc/doc.rs +++ b/src/librustdoc/doc.rs @@ -355,7 +355,11 @@ impl Item for StructDoc { pub trait ItemUtils { fn id(&self) -> AstId; - fn name(&self) -> ~str; + /// FIXME #5898: This conflicts with + /// syntax::attr::AttrMetaMethods.name; This rustdoc seems to be on + /// the way out so I'm making this one look bad rather than the + /// new methods in attr. + fn name_(&self) -> ~str; fn path(&self) -> ~[~str]; fn brief(&self) -> Option<~str>; fn desc(&self) -> Option<~str>; @@ -367,7 +371,7 @@ impl ItemUtils for A { self.item().id } - fn name(&self) -> ~str { + fn name_(&self) -> ~str { self.item().name.clone() } diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index 095066b164755..c027ba7e2f232 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -298,21 +298,21 @@ mod test { #[test] fn extract_mods() { let doc = mk_doc(@"mod a { mod b { } mod c { } }"); - assert!(doc.cratemod().mods()[0].name() == ~"a"); - assert!(doc.cratemod().mods()[0].mods()[0].name() == ~"b"); - assert!(doc.cratemod().mods()[0].mods()[1].name() == ~"c"); + assert!(doc.cratemod().mods()[0].name_() == ~"a"); + assert!(doc.cratemod().mods()[0].mods()[0].name_() == ~"b"); + assert!(doc.cratemod().mods()[0].mods()[1].name_() == ~"c"); } #[test] fn extract_fns_from_foreign_mods() { let doc = mk_doc(@"extern { fn a(); }"); - assert!(doc.cratemod().nmods()[0].fns[0].name() == ~"a"); + assert!(doc.cratemod().nmods()[0].fns[0].name_() == ~"a"); } #[test] fn extract_mods_deep() { let doc = mk_doc(@"mod a { mod b { mod c { } } }"); - assert!(doc.cratemod().mods()[0].mods()[0].mods()[0].name() == + assert!(doc.cratemod().mods()[0].mods()[0].mods()[0].name_() == ~"c"); } @@ -328,8 +328,8 @@ mod test { @"fn a() { } \ mod b { fn c() { } }"); - assert!(doc.cratemod().fns()[0].name() == ~"a"); - assert!(doc.cratemod().mods()[0].fns()[0].name() == ~"c"); + assert!(doc.cratemod().fns()[0].name_() == ~"a"); + assert!(doc.cratemod().mods()[0].fns()[0].name_() == ~"c"); } #[test] @@ -343,7 +343,7 @@ mod test { let source = @""; let ast = parse::from_str(source); let doc = extract(ast, ~"burp"); - assert!(doc.cratemod().name() == ~"burp"); + assert!(doc.cratemod().name_() == ~"burp"); } #[test] @@ -351,7 +351,7 @@ mod test { let source = ~""; do astsrv::from_str(source) |srv| { let doc = from_srv(srv, ~"name"); - assert!(doc.cratemod().name() == ~"name"); + assert!(doc.cratemod().name_() == ~"name"); } } @@ -359,14 +359,14 @@ mod test { fn should_extract_const_name_and_id() { let doc = mk_doc(@"static a: int = 0;"); assert!(doc.cratemod().consts()[0].id() != 0); - assert!(doc.cratemod().consts()[0].name() == ~"a"); + assert!(doc.cratemod().consts()[0].name_() == ~"a"); } #[test] fn should_extract_enums() { let doc = mk_doc(@"enum e { v }"); assert!(doc.cratemod().enums()[0].id() != 0); - assert!(doc.cratemod().enums()[0].name() == ~"e"); + assert!(doc.cratemod().enums()[0].name_() == ~"e"); } #[test] @@ -378,7 +378,7 @@ mod test { #[test] fn should_extract_traits() { let doc = mk_doc(@"trait i { fn f(); }"); - assert!(doc.cratemod().traits()[0].name() == ~"i"); + assert!(doc.cratemod().traits()[0].name_() == ~"i"); } #[test] @@ -396,13 +396,13 @@ mod test { #[test] fn should_extract_tys() { let doc = mk_doc(@"type a = int;"); - assert!(doc.cratemod().types()[0].name() == ~"a"); + assert!(doc.cratemod().types()[0].name_() == ~"a"); } #[test] fn should_extract_structs() { let doc = mk_doc(@"struct Foo { field: () }"); - assert!(doc.cratemod().structs()[0].name() == ~"Foo"); + assert!(doc.cratemod().structs()[0].name_() == ~"Foo"); } #[test] diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs index a1f4ddf986b0e..84b8febd33f54 100644 --- a/src/librustdoc/markdown_pass.rs +++ b/src/librustdoc/markdown_pass.rs @@ -172,7 +172,7 @@ pub fn header_kind(doc: doc::ItemTag) -> ~str { } pub fn header_name(doc: doc::ItemTag) -> ~str { - let fullpath = (doc.path() + &[doc.name()]).connect("::"); + let fullpath = (doc.path() + &[doc.name_()]).connect("::"); match &doc { &doc::ModTag(_) if doc.id() != syntax::ast::crate_node_id => { fullpath @@ -200,7 +200,7 @@ pub fn header_name(doc: doc::ItemTag) -> ~str { fmt!("%s for %s%s", trait_part, *self_ty, bounds) } _ => { - doc.name() + doc.name_() } } } diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs index 74ce1b650bce8..c13e85ea71659 100644 --- a/src/librustdoc/markdown_writer.rs +++ b/src/librustdoc/markdown_writer.rs @@ -159,12 +159,12 @@ pub fn make_filename( config.output_style == config::DocPerMod { ~"index" } else { - assert!(doc.topmod.name() != ~""); - doc.topmod.name() + assert!(doc.topmod.name_() != ~""); + doc.topmod.name_() } } doc::ItemPage(doc) => { - (doc.path() + &[doc.name()]).connect("_") + (doc.path() + &[doc.name_()]).connect("_") } } }; diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs index 4f1ce45cb60c0..7526b9557b2cb 100644 --- a/src/librustdoc/page_pass.rs +++ b/src/librustdoc/page_pass.rs @@ -174,7 +174,7 @@ mod test { fn should_make_a_page_for_every_mod() { let doc = mk_doc(~"mod a { }"); // hidden __std_macros module at the start. - assert_eq!(doc.pages.mods()[0].name(), ~"a"); + assert_eq!(doc.pages.mods()[0].name_(), ~"a"); } #[test] diff --git a/src/librustdoc/pass.rs b/src/librustdoc/pass.rs index 0654e1bbd1af1..aadc1b31acc52 100644 --- a/src/librustdoc/pass.rs +++ b/src/librustdoc/pass.rs @@ -48,7 +48,7 @@ fn test_run_passes() { doc::CratePage(doc::CrateDoc{ topmod: doc::ModDoc{ item: doc::ItemDoc { - name: doc.cratemod().name() + "two", + name: doc.cratemod().name_() + "two", .. doc.cratemod().item.clone() }, items: ~[], @@ -67,7 +67,7 @@ fn test_run_passes() { doc::CratePage(doc::CrateDoc{ topmod: doc::ModDoc{ item: doc::ItemDoc { - name: doc.cratemod().name() + "three", + name: doc.cratemod().name_() + "three", .. doc.cratemod().item.clone() }, items: ~[], @@ -91,6 +91,6 @@ fn test_run_passes() { ]; let doc = extract::from_srv(srv.clone(), ~"one"); let doc = run_passes(srv, doc, passes); - assert_eq!(doc.cratemod().name(), ~"onetwothree"); + assert_eq!(doc.cratemod().name_(), ~"onetwothree"); } } diff --git a/src/librustdoc/path_pass.rs b/src/librustdoc/path_pass.rs index 413df2f3358cf..1b7b6d578b9a5 100644 --- a/src/librustdoc/path_pass.rs +++ b/src/librustdoc/path_pass.rs @@ -68,7 +68,7 @@ fn fold_item(fold: &fold::Fold, doc: doc::ItemDoc) -> doc::ItemDoc { fn fold_mod(fold: &fold::Fold, doc: doc::ModDoc) -> doc::ModDoc { let is_topmod = doc.id() == ast::crate_node_id; - if !is_topmod { fold.ctxt.path.push(doc.name()); } + if !is_topmod { fold.ctxt.path.push(doc.name_()); } let doc = fold::default_any_fold_mod(fold, doc); if !is_topmod { fold.ctxt.path.pop(); } @@ -79,7 +79,7 @@ fn fold_mod(fold: &fold::Fold, doc: doc::ModDoc) -> doc::ModDoc { } fn fold_nmod(fold: &fold::Fold, doc: doc::NmodDoc) -> doc::NmodDoc { - fold.ctxt.path.push(doc.name()); + fold.ctxt.path.push(doc.name_()); let doc = fold::default_seq_fold_nmod(fold, doc); fold.ctxt.path.pop(); diff --git a/src/librustdoc/sort_item_name_pass.rs b/src/librustdoc/sort_item_name_pass.rs index 5ad0c5606d98c..8c7267e0b21c2 100644 --- a/src/librustdoc/sort_item_name_pass.rs +++ b/src/librustdoc/sort_item_name_pass.rs @@ -17,7 +17,7 @@ use sort_pass; pub fn mk_pass() -> Pass { fn by_item_name(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool { - (*item1).name() <= (*item2).name() + (*item1).name_() <= (*item2).name_() } sort_pass::mk_pass(~"sort_item_name", by_item_name) } @@ -32,7 +32,7 @@ fn test() { let doc = extract::from_srv(srv.clone(), ~""); let doc = (mk_pass().f)(srv.clone(), doc); // hidden __std_macros module at the start. - assert_eq!(doc.cratemod().items[1].name(), ~"y"); - assert_eq!(doc.cratemod().items[2].name(), ~"z"); + assert_eq!(doc.cratemod().items[1].name_(), ~"y"); + assert_eq!(doc.cratemod().items[2].name_(), ~"z"); } } diff --git a/src/librustdoc/sort_item_type_pass.rs b/src/librustdoc/sort_item_type_pass.rs index b37be5482ac6e..366cc83df2728 100644 --- a/src/librustdoc/sort_item_type_pass.rs +++ b/src/librustdoc/sort_item_type_pass.rs @@ -54,14 +54,14 @@ fn test() { let doc = extract::from_srv(srv.clone(), ~""); let doc = (mk_pass().f)(srv.clone(), doc); // hidden __std_macros module at the start. - assert_eq!(doc.cratemod().items[0].name(), ~"iconst"); - assert_eq!(doc.cratemod().items[1].name(), ~"itype"); - assert_eq!(doc.cratemod().items[2].name(), ~"ienum"); - assert_eq!(doc.cratemod().items[3].name(), ~"istruct"); - assert_eq!(doc.cratemod().items[4].name(), ~"itrait"); - assert_eq!(doc.cratemod().items[5].name(), ~"__extensions__"); - assert_eq!(doc.cratemod().items[6].name(), ~"ifn"); + assert_eq!(doc.cratemod().items[0].name_(), ~"iconst"); + assert_eq!(doc.cratemod().items[1].name_(), ~"itype"); + assert_eq!(doc.cratemod().items[2].name_(), ~"ienum"); + assert_eq!(doc.cratemod().items[3].name_(), ~"istruct"); + assert_eq!(doc.cratemod().items[4].name_(), ~"itrait"); + assert_eq!(doc.cratemod().items[5].name_(), ~"__extensions__"); + assert_eq!(doc.cratemod().items[6].name_(), ~"ifn"); // hidden __std_macros module fits here. - assert_eq!(doc.cratemod().items[8].name(), ~"imod"); + assert_eq!(doc.cratemod().items[8].name_(), ~"imod"); } } diff --git a/src/librustdoc/sort_pass.rs b/src/librustdoc/sort_pass.rs index 5119f1e3bfc81..a6aa9480f3827 100644 --- a/src/librustdoc/sort_pass.rs +++ b/src/librustdoc/sort_pass.rs @@ -68,7 +68,7 @@ fn fold_mod( #[test] fn test() { fn name_lteq(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool { - (*item1).name() <= (*item2).name() + (*item1).name_() <= (*item2).name_() } let source = ~"mod z { mod y { } fn x() { } } mod w { }"; @@ -76,10 +76,10 @@ fn test() { let doc = extract::from_srv(srv.clone(), ~""); let doc = (mk_pass(~"", name_lteq).f)(srv.clone(), doc); // hidden __std_macros module at the start. - assert_eq!(doc.cratemod().mods()[1].name(), ~"w"); - assert_eq!(doc.cratemod().mods()[2].items[0].name(), ~"x"); - assert_eq!(doc.cratemod().mods()[2].items[1].name(), ~"y"); - assert_eq!(doc.cratemod().mods()[2].name(), ~"z"); + assert_eq!(doc.cratemod().mods()[1].name_(), ~"w"); + assert_eq!(doc.cratemod().mods()[2].items[0].name_(), ~"x"); + assert_eq!(doc.cratemod().mods()[2].items[1].name_(), ~"y"); + assert_eq!(doc.cratemod().mods()[2].name_(), ~"z"); } } @@ -94,10 +94,10 @@ fn should_be_stable() { let doc = extract::from_srv(srv.clone(), ~""); let doc = (mk_pass(~"", always_eq).f)(srv.clone(), doc); // hidden __std_macros module at the start. - assert_eq!(doc.cratemod().mods()[1].items[0].name(), ~"b"); - assert_eq!(doc.cratemod().mods()[2].items[0].name(), ~"d"); + assert_eq!(doc.cratemod().mods()[1].items[0].name_(), ~"b"); + assert_eq!(doc.cratemod().mods()[2].items[0].name_(), ~"d"); let doc = (mk_pass(~"", always_eq).f)(srv.clone(), doc); - assert_eq!(doc.cratemod().mods()[1].items[0].name(), ~"b"); - assert_eq!(doc.cratemod().mods()[2].items[0].name(), ~"d"); + assert_eq!(doc.cratemod().mods()[1].items[0].name_(), ~"b"); + assert_eq!(doc.cratemod().mods()[2].items[0].name_(), ~"d"); } } diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index d2f5e00513c4c..13f3ce840714b 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -14,11 +14,9 @@ use rustc::metadata::filesearch; use extra::getopts::groups::getopts; use syntax::ast_util::*; use syntax::codemap::{dummy_sp, spanned}; -use syntax::codemap::dummy_spanned; use syntax::ext::base::ExtCtxt; use syntax::{ast, attr, codemap, diagnostic, fold}; -use syntax::ast::{meta_name_value, meta_list}; -use syntax::attr::{mk_attr}; +use syntax::attr::AttrMetaMethods; use rustc::back::link::output_type_exe; use rustc::driver::driver::compile_upto; use rustc::driver::session::{lib_crate, bin_crate}; @@ -81,7 +79,7 @@ fn fold_mod(_ctx: @mut ReadyCtx, fn strip_main(item: @ast::item) -> @ast::item { @ast::item { attrs: do item.attrs.iter().filter_map |attr| { - if "main" != attr::get_attr_name(attr) { + if "main" != attr.name() { Some(*attr) } else { None @@ -104,25 +102,27 @@ fn fold_item(ctx: @mut ReadyCtx, fold: @fold::ast_fold) -> Option<@ast::item> { ctx.path.push(item.ident); - let attrs = attr::find_attrs_by_name(item.attrs, "pkg_do"); + let mut cmds = ~[]; + let mut had_pkg_do = false; - if attrs.len() > 0 { - let mut cmds = ~[]; - - for attrs.iter().advance |attr| { + for item.attrs.iter().advance |attr| { + if "pkg_do" == attr.name() { + had_pkg_do = true; match attr.node.value.node { - ast::meta_list(_, ref mis) => { + ast::MetaList(_, ref mis) => { for mis.iter().advance |mi| { match mi.node { - ast::meta_word(cmd) => cmds.push(cmd.to_owned()), + ast::MetaWord(cmd) => cmds.push(cmd.to_owned()), _ => {} }; } } _ => cmds.push(~"build") - }; + } } + } + if had_pkg_do { ctx.fns.push(ListenerFn { cmds: cmds, span: item.span, @@ -245,14 +245,13 @@ pub fn compile_input(ctxt: &Ctx, _ => pkg_id.short_name.clone() }; debug!("Injecting link name: %s", short_name_to_use); + let link_options = + ~[attr::mk_name_value_item_str(@"name", short_name_to_use.to_managed()), + attr::mk_name_value_item_str(@"vers", pkg_id.version.to_str().to_managed())]; + crate = @codemap::respan(crate.span, ast::crate_ { - attrs: ~[mk_attr(@dummy_spanned( - meta_list(@"link", - ~[@dummy_spanned(meta_name_value(@"name", - mk_string_lit(short_name_to_use.to_managed()))), - @dummy_spanned(meta_name_value(@"vers", - mk_string_lit(pkg_id.version.to_str().to_managed())))])))], - ..crate.node.clone()}); + attrs: ~[attr::mk_attr(attr::mk_list_item(@"link", link_options))], + .. crate.node.clone()}); } debug!("calling compile_crate_from_input, out_dir = %s, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7fa2c2700c938..f2974423a1a62 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -193,26 +193,51 @@ pub enum def { } -// The set of meta_items that define the compilation environment of the crate, +// The set of MetaItems that define the compilation environment of the crate, // used to drive conditional compilation -pub type crate_cfg = ~[@meta_item]; +pub type crate_cfg = ~[@MetaItem]; pub type crate = spanned; #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub struct crate_ { module: _mod, - attrs: ~[attribute], + attrs: ~[Attribute], config: crate_cfg, } -pub type meta_item = spanned; +pub type MetaItem = spanned; -#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] -pub enum meta_item_ { - meta_word(@str), - meta_list(@str, ~[@meta_item]), - meta_name_value(@str, lit), +#[deriving(Clone, Encodable, Decodable, IterBytes)] +pub enum MetaItem_ { + MetaWord(@str), + MetaList(@str, ~[@MetaItem]), + MetaNameValue(@str, lit), +} + +// can't be derived because the MetaList requires an unordered comparison +impl Eq for MetaItem_ { + fn eq(&self, other: &MetaItem_) -> bool { + match *self { + MetaWord(ref ns) => match *other { + MetaWord(ref no) => (*ns) == (*no), + _ => false + }, + MetaNameValue(ref ns, ref vs) => match *other { + MetaNameValue(ref no, ref vo) => { + (*ns) == (*no) && vs.node == vo.node + } + _ => false + }, + MetaList(ref ns, ref miss) => match *other { + MetaList(ref no, ref miso) => { + ns == no && + miss.iter().all(|mi| miso.iter().any(|x| x.node == mi.node)) + } + _ => false + } + } + } } //pub type blk = spanned; @@ -622,7 +647,7 @@ pub type ty_field = spanned; #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub struct ty_method { ident: ident, - attrs: ~[attribute], + attrs: ~[Attribute], purity: purity, decl: fn_decl, generics: Generics, @@ -833,7 +858,7 @@ pub type explicit_self = spanned; #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct method { ident: ident, - attrs: ~[attribute], + attrs: ~[Attribute], generics: Generics, explicit_self: explicit_self, purity: purity, @@ -886,7 +911,7 @@ pub struct enum_def { #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub struct variant_ { name: ident, - attrs: ~[attribute], + attrs: ~[Attribute], kind: variant_kind, id: node_id, disr_expr: Option<@expr>, @@ -925,34 +950,34 @@ pub enum view_path_ { #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub struct view_item { node: view_item_, - attrs: ~[attribute], + attrs: ~[Attribute], vis: visibility, span: span, } #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub enum view_item_ { - view_item_extern_mod(ident, ~[@meta_item], node_id), + view_item_extern_mod(ident, ~[@MetaItem], node_id), view_item_use(~[@view_path]), } // Meta-data associated with an item -pub type attribute = spanned; +pub type Attribute = spanned; -// Distinguishes between attributes that decorate items and attributes that +// Distinguishes between Attributes that decorate items and Attributes that // are contained as statements within items. These two cases need to be // distinguished for pretty-printing. #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)] -pub enum attr_style { - attr_outer, - attr_inner, +pub enum AttrStyle { + AttrOuter, + AttrInner, } // doc-comments are promoted to attributes that have is_sugared_doc = true #[deriving(Clone, Eq, Encodable, Decodable,IterBytes)] -pub struct attribute_ { - style: attr_style, - value: @meta_item, +pub struct Attribute_ { + style: AttrStyle, + value: @MetaItem, is_sugared_doc: bool, } @@ -990,7 +1015,7 @@ pub struct struct_field_ { kind: struct_field_kind, id: node_id, ty: Ty, - attrs: ~[attribute], + attrs: ~[Attribute], } pub type struct_field = spanned; @@ -1016,7 +1041,7 @@ pub struct struct_def { #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] pub struct item { ident: ident, - attrs: ~[attribute], + attrs: ~[Attribute], id: node_id, node: item_, vis: visibility, @@ -1044,7 +1069,7 @@ pub enum item_ { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct foreign_item { ident: ident, - attrs: ~[attribute], + attrs: ~[Attribute], node: foreign_item_, id: node_id, span: span, diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 7dd01a54f7a95..3c560d211fd27 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -8,313 +8,256 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Functions dealing with attributes and meta_items +// Functions dealing with attributes and meta items use extra; use ast; +use ast::{Attribute, Attribute_, MetaItem, MetaWord, MetaNameValue, MetaList}; use codemap::{spanned, dummy_spanned}; -use attr; use codemap::BytePos; use diagnostic::span_handler; use parse::comments::{doc_comment_style, strip_doc_comment_decoration}; use std::hashmap::HashSet; -/* Constructors */ - -pub fn mk_name_value_item_str(name: @str, value: @str) - -> @ast::meta_item { - let value_lit = dummy_spanned(ast::lit_str(value)); - mk_name_value_item(name, value_lit) -} - -pub fn mk_name_value_item(name: @str, value: ast::lit) - -> @ast::meta_item { - @dummy_spanned(ast::meta_name_value(name, value)) -} - -pub fn mk_list_item(name: @str, items: ~[@ast::meta_item]) -> - @ast::meta_item { - @dummy_spanned(ast::meta_list(name, items)) -} -pub fn mk_word_item(name: @str) -> @ast::meta_item { - @dummy_spanned(ast::meta_word(name)) +pub trait AttrMetaMethods { + // This could be changed to `fn check_name(&self, name: @str) -> + // bool` which would facilitate a side table recording which + // attributes/meta items are used/unused. + + /// Retrieve the name of the meta item, e.g. foo in #[foo], + /// #[foo="bar"] and #[foo(bar)] + fn name(&self) -> @str; + + /** + * Gets the string value if self is a MetaNameValue variant + * containing a string, otherwise None. + */ + fn value_str(&self) -> Option<@str>; + /// Gets a list of inner meta items from a list MetaItem type. + fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]>; + + /** + * If the meta item is a name-value type with a string value then returns + * a tuple containing the name and string value, otherwise `None` + */ + fn name_str_pair(&self) -> Option<(@str, @str)>; } -pub fn mk_attr(item: @ast::meta_item) -> ast::attribute { - dummy_spanned(ast::attribute_ { style: ast::attr_inner, - value: item, - is_sugared_doc: false }) +impl AttrMetaMethods for Attribute { + fn name(&self) -> @str { self.meta().name() } + fn value_str(&self) -> Option<@str> { self.meta().value_str() } + fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]> { + self.node.value.meta_item_list() + } + fn name_str_pair(&self) -> Option<(@str, @str)> { self.meta().name_str_pair() } } -pub fn mk_sugared_doc_attr(text: @str, - lo: BytePos, hi: BytePos) -> ast::attribute { - let style = doc_comment_style(text); - let lit = spanned(lo, hi, ast::lit_str(text)); - let attr = ast::attribute_ { - style: style, - value: @spanned(lo, hi, ast::meta_name_value(@"doc", lit)), - is_sugared_doc: true - }; - spanned(lo, hi, attr) -} +impl AttrMetaMethods for MetaItem { + fn name(&self) -> @str { + match self.node { + MetaWord(n) => n, + MetaNameValue(n, _) => n, + MetaList(n, _) => n + } + } -/* Conversion */ + fn value_str(&self) -> Option<@str> { + match self.node { + MetaNameValue(_, ref v) => { + match v.node { + ast::lit_str(s) => Some(s), + _ => None, + } + }, + _ => None + } + } -pub fn attr_meta(attr: ast::attribute) -> @ast::meta_item { - attr.node.value -} + fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]> { + match self.node { + MetaList(_, ref l) => Some(l.as_slice()), + _ => None + } + } -// Get the meta_items from inside a vector of attributes -pub fn attr_metas(attrs: &[ast::attribute]) -> ~[@ast::meta_item] { - do attrs.map |a| { attr_meta(*a) } + pub fn name_str_pair(&self) -> Option<(@str, @str)> { + self.value_str().map_consume(|s| (self.name(), s)) + } } -pub fn desugar_doc_attr(attr: &ast::attribute) -> ast::attribute { - if attr.node.is_sugared_doc { - let comment = get_meta_item_value_str(attr.node.value).get(); - let meta = mk_name_value_item_str(@"doc", - strip_doc_comment_decoration(comment).to_managed()); - mk_attr(meta) - } else { - *attr +// Annoying, but required to get test_cfg to work +impl AttrMetaMethods for @MetaItem { + fn name(&self) -> @str { (**self).name() } + fn value_str(&self) -> Option<@str> { (**self).value_str() } + fn meta_item_list<'a>(&'a self) -> Option<&'a [@MetaItem]> { + (**self).meta_item_list() } + fn name_str_pair(&self) -> Option<(@str, @str)> { (**self).name_str_pair() } } -/* Accessors */ -pub fn get_attr_name(attr: &ast::attribute) -> @str { - get_meta_item_name(attr.node.value) +pub trait AttributeMethods { + fn meta(&self) -> @MetaItem; + fn desugar_doc(&self) -> Attribute; } -pub fn get_meta_item_name(meta: @ast::meta_item) -> @str { - match meta.node { - ast::meta_word(n) => n, - ast::meta_name_value(n, _) => n, - ast::meta_list(n, _) => n, +impl AttributeMethods for Attribute { + /// Extract the MetaItem from inside this Attribute. + pub fn meta(&self) -> @MetaItem { + self.node.value } -} -/** - * Gets the string value if the meta_item is a meta_name_value variant - * containing a string, otherwise none - */ -pub fn get_meta_item_value_str(meta: @ast::meta_item) -> Option<@str> { - match meta.node { - ast::meta_name_value(_, v) => { - match v.node { - ast::lit_str(s) => Some(s), - _ => None, - } - }, - _ => None + /// Convert self to a normal #[doc="foo"] comment, if it is a + /// comment like `///` or `/** */`. (Returns self unchanged for + /// non-sugared doc attributes.) + pub fn desugar_doc(&self) -> Attribute { + if self.node.is_sugared_doc { + let comment = self.value_str().get(); + let meta = mk_name_value_item_str(@"doc", + strip_doc_comment_decoration(comment).to_managed()); + mk_attr(meta) + } else { + *self + } } } -/// Gets a list of inner meta items from a list meta_item type -pub fn get_meta_item_list(meta: @ast::meta_item) - -> Option<~[@ast::meta_item]> { - match meta.node { - ast::meta_list(_, ref l) => Some(/* FIXME (#2543) */ (*l).clone()), - _ => None - } -} +/* Constructors */ -/** - * If the meta item is a nam-value type with a string value then returns - * a tuple containing the name and string value, otherwise `none` - */ -pub fn get_name_value_str_pair(item: @ast::meta_item) - -> Option<(@str, @str)> { - match attr::get_meta_item_value_str(item) { - Some(value) => { - let name = attr::get_meta_item_name(item); - Some((name, value)) - } - None => None - } +pub fn mk_name_value_item_str(name: @str, value: @str) -> @MetaItem { + let value_lit = dummy_spanned(ast::lit_str(value)); + mk_name_value_item(name, value_lit) } - -/* Searching */ - -/// Search a list of attributes and return only those with a specific name -pub fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) -> - ~[ast::attribute] { - do attrs.iter().filter_map |a| { - if name == get_attr_name(a) { - Some(*a) - } else { - None - } - }.collect() +pub fn mk_name_value_item(name: @str, value: ast::lit) -> @MetaItem { + @dummy_spanned(MetaNameValue(name, value)) } -/// Search a list of meta items and return only those with a specific name -pub fn find_meta_items_by_name(metas: &[@ast::meta_item], name: &str) -> - ~[@ast::meta_item] { - let mut rs = ~[]; - for metas.iter().advance |mi| { - if name == get_meta_item_name(*mi) { - rs.push(*mi) - } - } - rs +pub fn mk_list_item(name: @str, items: ~[@MetaItem]) -> @MetaItem { + @dummy_spanned(MetaList(name, items)) } -/** - * Returns true if a list of meta items contains another meta item. The - * comparison is performed structurally. - */ -pub fn contains(haystack: &[@ast::meta_item], - needle: @ast::meta_item) -> bool { - for haystack.iter().advance |item| { - if eq(*item, needle) { return true; } - } - return false; +pub fn mk_word_item(name: @str) -> @MetaItem { + @dummy_spanned(MetaWord(name)) } -fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool { - match a.node { - ast::meta_word(ref na) => match b.node { - ast::meta_word(ref nb) => (*na) == (*nb), - _ => false - }, - ast::meta_name_value(ref na, va) => match b.node { - ast::meta_name_value(ref nb, vb) => { - (*na) == (*nb) && va.node == vb.node - } - _ => false - }, - ast::meta_list(ref na, ref misa) => match b.node { - ast::meta_list(ref nb, ref misb) => { - if na != nb { return false; } - for misa.iter().advance |mi| { - if !misb.iter().any(|x| x == mi) { return false; } - } - true - } - _ => false - } - } +pub fn mk_attr(item: @MetaItem) -> Attribute { + dummy_spanned(Attribute_ { + style: ast::AttrInner, + value: item, + is_sugared_doc: false, + }) } -pub fn contains_name(metas: &[@ast::meta_item], name: &str) -> bool { - let matches = find_meta_items_by_name(metas, name); - matches.len() > 0u +pub fn mk_sugared_doc_attr(text: @str, lo: BytePos, hi: BytePos) -> Attribute { + let style = doc_comment_style(text); + let lit = spanned(lo, hi, ast::lit_str(text)); + let attr = Attribute_ { + style: style, + value: @spanned(lo, hi, MetaNameValue(@"doc", lit)), + is_sugared_doc: true + }; + spanned(lo, hi, attr) } -pub fn attrs_contains_name(attrs: &[ast::attribute], name: &str) -> bool { - !find_attrs_by_name(attrs, name).is_empty() +/* Searching */ +/// Check if `needle` occurs in `haystack` by a structural +/// comparison. This is slightly subtle, and relies on ignoring the +/// span included in the `==` comparison a plain MetaItem. +pub fn contains(haystack: &[@ast::MetaItem], + needle: @ast::MetaItem) -> bool { + debug!("attr::contains (name=%s)", needle.name()); + do haystack.iter().any |item| { + debug!(" testing: %s", item.name()); + item.node == needle.node + } } -pub fn first_attr_value_str_by_name(attrs: &[ast::attribute], name: &str) - -> Option<@str> { - - let mattrs = find_attrs_by_name(attrs, name); - if mattrs.len() > 0 { - get_meta_item_value_str(attr_meta(mattrs[0])) - } else { - None +pub fn contains_name(metas: &[AM], name: &str) -> bool { + debug!("attr::contains_name (name=%s)", name); + do metas.iter().any |item| { + debug!(" testing: %s", item.name()); + name == item.name() } } -fn last_meta_item_by_name(items: &[@ast::meta_item], name: &str) - -> Option<@ast::meta_item> { - - let items = attr::find_meta_items_by_name(items, name); - items.last_opt().map(|item| **item) +pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: &str) + -> Option<@str> { + attrs.iter() + .find_(|at| name == at.name()) + .chain(|at| at.value_str()) } -pub fn last_meta_item_value_str_by_name(items: &[@ast::meta_item], name: &str) +pub fn last_meta_item_value_str_by_name(items: &[@MetaItem], name: &str) -> Option<@str> { - - match last_meta_item_by_name(items, name) { - Some(item) => { - match attr::get_meta_item_value_str(item) { - Some(value) => Some(value), - None => None - } - }, - None => None - } + items.rev_iter().find_(|mi| name == mi.name()).chain(|i| i.value_str()) } -pub fn last_meta_item_list_by_name(items: ~[@ast::meta_item], name: &str) - -> Option<~[@ast::meta_item]> { - - match last_meta_item_by_name(items, name) { - Some(item) => attr::get_meta_item_list(item), - None => None - } -} - - /* Higher-level applications */ -pub fn sort_meta_items(items: &[@ast::meta_item]) -> ~[@ast::meta_item] { - // This is sort of stupid here, converting to a vec of mutables and back - let mut v = items.to_owned(); - do extra::sort::quick_sort(v) |ma, mb| { - get_meta_item_name(*ma) <= get_meta_item_name(*mb) +pub fn sort_meta_items(items: &[@MetaItem]) -> ~[@MetaItem] { + // This is sort of stupid here, but we need to sort by + // human-readable strings. + let mut v = items.iter() + .transform(|&mi| (mi.name(), mi)) + .collect::<~[(@str, @MetaItem)]>(); + + do extra::sort::quick_sort(v) |&(a, _), &(b, _)| { + a <= b } // There doesn't seem to be a more optimal way to do this - do v.map |m| { + do v.consume_iter().transform |(_, m)| { match m.node { - ast::meta_list(n, ref mis) => { + MetaList(n, ref mis) => { @spanned { - node: ast::meta_list(n, sort_meta_items(*mis)), - .. /*bad*/ (**m).clone() + node: MetaList(n, sort_meta_items(*mis)), + .. /*bad*/ (*m).clone() } } - _ => *m + _ => m } - } -} - -pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: &str) -> - ~[@ast::meta_item] { - items.consume_iter().filter(|item| name != get_meta_item_name(*item)).collect() + }.collect() } /** * From a list of crate attributes get only the meta_items that affect crate * linkage */ -pub fn find_linkage_metas(attrs: &[ast::attribute]) -> ~[@ast::meta_item] { - do find_attrs_by_name(attrs, "link").flat_map |attr| { - match attr.node.value.node { - ast::meta_list(_, ref items) => { - /* FIXME (#2543) */ (*items).clone() - } - _ => ~[] +pub fn find_linkage_metas(attrs: &[Attribute]) -> ~[@MetaItem] { + let mut result = ~[]; + for attrs.iter().filter(|at| "link" == at.name()).advance |attr| { + match attr.meta().node { + MetaList(_, ref items) => result.push_all(*items), + _ => () } } + result } #[deriving(Eq)] -pub enum inline_attr { - ia_none, - ia_hint, - ia_always, - ia_never, +pub enum InlineAttr { + InlineNone, + InlineHint, + InlineAlways, + InlineNever, } /// True if something like #[inline] is found in the list of attrs. -pub fn find_inline_attr(attrs: &[ast::attribute]) -> inline_attr { +pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr { // FIXME (#2809)---validate the usage of #[inline] and #[inline] - do attrs.iter().fold(ia_none) |ia,attr| { + do attrs.iter().fold(InlineNone) |ia,attr| { match attr.node.value.node { - ast::meta_word(s) if "inline" == s => ia_hint, - ast::meta_list(s, ref items) if "inline" == s => { - if !find_meta_items_by_name(*items, "always").is_empty() { - ia_always - } else if !find_meta_items_by_name(*items, "never").is_empty() { - ia_never + MetaWord(n) if "inline" == n => InlineHint, + MetaList(n, ref items) if "inline" == n => { + if contains_name(*items, "always") { + InlineAlways + } else if contains_name(*items, "never") { + InlineNever } else { - ia_hint + InlineHint } } _ => ia @@ -322,12 +265,59 @@ pub fn find_inline_attr(attrs: &[ast::attribute]) -> inline_attr { } } +/// Tests if any `cfg(...)` meta items in `metas` match `cfg`. e.g. +/// +/// test_cfg(`[foo="a", bar]`, `[cfg(foo), cfg(bar)]`) == true +/// test_cfg(`[foo="a", bar]`, `[cfg(not(bar))]`) == false +/// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="a")]`) == true +/// test_cfg(`[foo="a", bar]`, `[cfg(bar, foo="b")]`) == false +pub fn test_cfg> + (cfg: &[@MetaItem], mut metas: It) -> bool { + // having no #[cfg(...)] attributes counts as matching. + let mut no_cfgs = true; + + // this would be much nicer as a chain of iterator adaptors, but + // this doesn't work. + let some_cfg_matches = do metas.any |mi| { + debug!("testing name: %s", mi.name()); + if "cfg" == mi.name() { // it is a #[cfg()] attribute + debug!("is cfg"); + no_cfgs = false; + // only #[cfg(...)] ones are understood. + match mi.meta_item_list() { + Some(cfg_meta) => { + debug!("is cfg(...)"); + do cfg_meta.iter().all |cfg_mi| { + debug!("cfg(%s[...])", cfg_mi.name()); + match cfg_mi.node { + ast::MetaList(s, ref not_cfgs) if "not" == s => { + debug!("not!"); + // inside #[cfg(not(...))], so these need to all + // not match. + not_cfgs.iter().all(|mi| { + debug!("cfg(not(%s[...]))", mi.name()); + !contains(cfg, *mi) + }) + } + _ => contains(cfg, *cfg_mi) + } + } + } + None => false + } + } else { + false + } + }; + debug!("test_cfg (no_cfgs=%?, some_cfg_matches=%?)", no_cfgs, some_cfg_matches); + no_cfgs || some_cfg_matches +} pub fn require_unique_names(diagnostic: @span_handler, - metas: &[@ast::meta_item]) { + metas: &[@MetaItem]) { let mut set = HashSet::new(); for metas.iter().advance |meta| { - let name = get_meta_item_name(*meta); + let name = meta.name(); // FIXME: How do I silence the warnings? --pcw (#2619) if !set.insert(name) { diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 64d2644b38310..4ada7f7479b75 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -17,7 +17,7 @@ use ext::base::*; pub fn expand_auto_encode( cx: @ExtCtxt, span: span, - _mitem: @ast::meta_item, + _mitem: @ast::MetaItem, in_items: ~[@ast::item] ) -> ~[@ast::item] { cx.span_err(span, "`#[auto_encode]` is deprecated, use `#[deriving(Encodable)]` instead"); @@ -27,7 +27,7 @@ pub fn expand_auto_encode( pub fn expand_auto_decode( cx: @ExtCtxt, span: span, - _mitem: @ast::meta_item, + _mitem: @ast::MetaItem, in_items: ~[@ast::item] ) -> ~[@ast::item] { cx.span_err(span, "`#[auto_decode]` is deprecated, use `#[deriving(Decodable)]` instead"); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 230640767c9b4..c71ea78bba5c5 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -36,7 +36,7 @@ pub struct MacroDef { pub type ItemDecorator = @fn(@ExtCtxt, span, - @ast::meta_item, + @ast::MetaItem, ~[@ast::item]) -> ~[@ast::item]; diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 59754f5519ee6..df5f3d8d89545 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -163,7 +163,7 @@ pub trait AstBuilder { // items fn item(&self, span: span, - name: ident, attrs: ~[ast::attribute], node: ast::item_) -> @ast::item; + name: ident, attrs: ~[ast::Attribute], node: ast::item_) -> @ast::item; fn arg(&self, span: span, name: ident, ty: ast::Ty) -> ast::arg; // XXX unused self @@ -199,7 +199,7 @@ pub trait AstBuilder { fn item_struct(&self, span: span, name: ident, struct_def: ast::struct_def) -> @ast::item; fn item_mod(&self, span: span, - name: ident, attrs: ~[ast::attribute], + name: ident, attrs: ~[ast::Attribute], vi: ~[ast::view_item], items: ~[@ast::item]) -> @ast::item; fn item_ty_poly(&self, @@ -209,11 +209,11 @@ pub trait AstBuilder { generics: Generics) -> @ast::item; fn item_ty(&self, span: span, name: ident, ty: ast::Ty) -> @ast::item; - fn attribute(&self, sp: span, mi: @ast::meta_item) -> ast::attribute; + fn attribute(&self, sp: span, mi: @ast::MetaItem) -> ast::Attribute; - fn meta_word(&self, sp: span, w: @str) -> @ast::meta_item; - fn meta_list(&self, sp: span, name: @str, mis: ~[@ast::meta_item]) -> @ast::meta_item; - fn meta_name_value(&self, sp: span, name: @str, value: ast::lit_) -> @ast::meta_item; + fn meta_word(&self, sp: span, w: @str) -> @ast::MetaItem; + fn meta_list(&self, sp: span, name: @str, mis: ~[@ast::MetaItem]) -> @ast::MetaItem; + fn meta_name_value(&self, sp: span, name: @str, value: ast::lit_) -> @ast::MetaItem; fn view_use(&self, sp: span, vis: ast::visibility, vp: ~[@ast::view_path]) -> ast::view_item; @@ -657,7 +657,7 @@ impl AstBuilder for @ExtCtxt { } fn item(&self, span: span, - name: ident, attrs: ~[ast::attribute], node: ast::item_) -> @ast::item { + name: ident, attrs: ~[ast::Attribute], node: ast::item_) -> @ast::item { // XXX: Would be nice if our generated code didn't violate // Rust coding conventions @ast::item { ident: name, @@ -754,7 +754,7 @@ impl AstBuilder for @ExtCtxt { } fn item_mod(&self, span: span, name: ident, - attrs: ~[ast::attribute], + attrs: ~[ast::Attribute], vi: ~[ast::view_item], items: ~[@ast::item]) -> @ast::item { self.item( @@ -777,23 +777,22 @@ impl AstBuilder for @ExtCtxt { self.item_ty_poly(span, name, ty, ast_util::empty_generics()) } - fn attribute(&self, sp: span, mi: @ast::meta_item) -> ast::attribute { - respan(sp, - ast::attribute_ { - style: ast::attr_outer, - value: mi, - is_sugared_doc: false - }) + fn attribute(&self, sp: span, mi: @ast::MetaItem) -> ast::Attribute { + respan(sp, ast::Attribute_ { + style: ast::AttrOuter, + value: mi, + is_sugared_doc: false, + }) } - fn meta_word(&self, sp: span, w: @str) -> @ast::meta_item { - @respan(sp, ast::meta_word(w)) + fn meta_word(&self, sp: span, w: @str) -> @ast::MetaItem { + @respan(sp, ast::MetaWord(w)) } - fn meta_list(&self, sp: span, name: @str, mis: ~[@ast::meta_item]) -> @ast::meta_item { - @respan(sp, ast::meta_list(name, mis)) + fn meta_list(&self, sp: span, name: @str, mis: ~[@ast::MetaItem]) -> @ast::MetaItem { + @respan(sp, ast::MetaList(name, mis)) } - fn meta_name_value(&self, sp: span, name: @str, value: ast::lit_) -> @ast::meta_item { - @respan(sp, ast::meta_name_value(name, respan(sp, value))) + fn meta_name_value(&self, sp: span, name: @str, value: ast::lit_) -> @ast::MetaItem { + @respan(sp, ast::MetaNameValue(name, respan(sp, value))) } fn view_use(&self, sp: span, diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index edaf2b8cae674..02dcb2cdbc9eb 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{meta_item, item, expr}; +use ast::{MetaItem, item, expr}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; @@ -16,7 +16,7 @@ use ext::deriving::generic::*; pub fn expand_deriving_clone(cx: @ExtCtxt, span: span, - mitem: @meta_item, + mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { @@ -40,9 +40,9 @@ pub fn expand_deriving_clone(cx: @ExtCtxt, } pub fn expand_deriving_deep_clone(cx: @ExtCtxt, - span: span, - mitem: @meta_item, - in_items: ~[@item]) + span: span, + mitem: @MetaItem, + in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { path: Path::new(~["std", "clone", "DeepClone"]), diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index cea88bb7bbb75..a7d9db59130f3 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{meta_item, item, expr}; +use ast::{MetaItem, item, expr}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; @@ -16,7 +16,7 @@ use ext::deriving::generic::*; pub fn expand_deriving_eq(cx: @ExtCtxt, span: span, - mitem: @meta_item, + mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { // structures are equal if all fields are equal, and non equal, if // any fields are not equal or if the enum variants are different diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 3b9691cd42c00..d532eedd2918e 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -9,7 +9,7 @@ // except according to those terms. use ast; -use ast::{meta_item, item, expr}; +use ast::{MetaItem, item, expr}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; @@ -17,7 +17,7 @@ use ext::deriving::generic::*; pub fn expand_deriving_ord(cx: @ExtCtxt, span: span, - mitem: @meta_item, + mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { macro_rules! md ( ($name:expr, $op:expr, $equal:expr) => { diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index 70ac4d3d4c18d..8285de1d56198 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -8,17 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{meta_item, item, expr}; +use ast::{MetaItem, item, expr}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; use ext::deriving::generic::*; pub fn expand_deriving_totaleq(cx: @ExtCtxt, - span: span, - mitem: @meta_item, - in_items: ~[@item]) -> ~[@item] { - + span: span, + mitem: @MetaItem, + in_items: ~[@item]) -> ~[@item] { fn cs_equals(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { cs_and(|cx, span, _, _| cx.expr_bool(span, false), cx, span, substr) diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs index 84d7320fe1c19..01dacdfe453ee 100644 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ b/src/libsyntax/ext/deriving/cmp/totalord.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{meta_item, item, expr}; +use ast::{MetaItem, item, expr}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; @@ -17,7 +17,7 @@ use std::cmp::{Ordering, Equal, Less, Greater}; pub fn expand_deriving_totalord(cx: @ExtCtxt, span: span, - mitem: @meta_item, + mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { path: Path::new(~["std", "cmp", "TotalOrd"]), diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 405f9e3438beb..bde0a345b1022 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -16,7 +16,7 @@ encodable.rs for more. use std::vec; use std::uint; -use ast::{meta_item, item, expr, m_mutbl}; +use ast::{MetaItem, item, expr, m_mutbl}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; @@ -24,7 +24,7 @@ use ext::deriving::generic::*; pub fn expand_deriving_decodable(cx: @ExtCtxt, span: span, - mitem: @meta_item, + mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { path: Path::new_(~["extra", "serialize", "Decodable"], None, diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 5514fd0b6ab5b..1f969b4e0781f 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -75,7 +75,7 @@ would yield functions like: } */ -use ast::{meta_item, item, expr, m_imm, m_mutbl}; +use ast::{MetaItem, item, expr, m_imm, m_mutbl}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; @@ -83,7 +83,7 @@ use ext::deriving::generic::*; pub fn expand_deriving_encodable(cx: @ExtCtxt, span: span, - mitem: @meta_item, + mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { path: Path::new_(~["extra", "serialize", "Encodable"], None, diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index a50f4d70f0e9e..04bbe5ae1d6a9 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -281,7 +281,7 @@ pub type EnumNonMatchFunc<'self> = impl<'self> TraitDef<'self> { pub fn expand(&self, cx: @ExtCtxt, span: span, - _mitem: @ast::meta_item, + _mitem: @ast::MetaItem, in_items: ~[@ast::item]) -> ~[@ast::item] { let mut result = ~[]; for in_items.iter().advance |item| { @@ -361,7 +361,8 @@ impl<'self> TraitDef<'self> { let doc_attr = cx.attribute( span, cx.meta_name_value(span, - @"doc", ast::lit_str(@"Automatically derived."))); + @"doc", + ast::lit_str(@"Automatically derived."))); cx.item( span, ::parse::token::special_idents::clownshoes_extensions, diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index be13e103a721b..57a4f0899b528 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{meta_item, item, expr, and}; +use ast::{MetaItem, item, expr, and}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; @@ -17,7 +17,7 @@ use ext::deriving::generic::*; pub fn expand_deriving_iter_bytes(cx: @ExtCtxt, span: span, - mitem: @meta_item, + mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { path: Path::new(~["std", "to_bytes", "IterBytes"]), diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index 537d9efbb26d9..cde7dcc5dbe2a 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -18,7 +18,8 @@ library. */ -use ast::{enum_def, ident, item, Generics, meta_item, struct_def}; +use ast::{enum_def, ident, item, Generics, struct_def}; +use ast::{MetaItem, MetaList, MetaNameValue, MetaWord}; use ext::base::ExtCtxt; use ext::build::AstBuilder; use codemap::span; @@ -58,26 +59,24 @@ pub type ExpandDerivingEnumDefFn<'self> = &'self fn(@ExtCtxt, pub fn expand_meta_deriving(cx: @ExtCtxt, _span: span, - mitem: @meta_item, + mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { - use ast::{meta_list, meta_name_value, meta_word}; - match mitem.node { - meta_name_value(_, ref l) => { + MetaNameValue(_, ref l) => { cx.span_err(l.span, "unexpected value in `deriving`"); in_items } - meta_word(_) | meta_list(_, []) => { + MetaWord(_) | MetaList(_, []) => { cx.span_warn(mitem.span, "empty trait list in `deriving`"); in_items } - meta_list(_, ref titems) => { + MetaList(_, ref titems) => { do titems.rev_iter().fold(in_items) |in_items, &titem| { match titem.node { - meta_name_value(tname, _) | - meta_list(tname, _) | - meta_word(tname) => { + MetaNameValue(tname, _) | + MetaList(tname, _) | + MetaWord(tname) => { macro_rules! expand(($func:path) => ($func(cx, titem.span, titem, in_items))); match tname.as_slice() { diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index 823f21401ca2d..2966a8c114daf 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -9,7 +9,7 @@ // except according to those terms. use ast; -use ast::{meta_item, item, expr, ident}; +use ast::{MetaItem, item, expr, ident}; use codemap::span; use ext::base::ExtCtxt; use ext::build::{AstBuilder, Duplicate}; @@ -19,7 +19,7 @@ use std::vec; pub fn expand_deriving_rand(cx: @ExtCtxt, span: span, - mitem: @meta_item, + mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs index c9d63d2c41679..9b544eb0796a2 100644 --- a/src/libsyntax/ext/deriving/to_str.rs +++ b/src/libsyntax/ext/deriving/to_str.rs @@ -9,7 +9,7 @@ // except according to those terms. use ast; -use ast::{meta_item, item, expr}; +use ast::{MetaItem, item, expr}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; @@ -17,7 +17,7 @@ use ext::deriving::generic::*; pub fn expand_deriving_to_str(cx: @ExtCtxt, span: span, - mitem: @meta_item, + mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs index 5bee804d58250..3c9e842473c1c 100644 --- a/src/libsyntax/ext/deriving/zero.rs +++ b/src/libsyntax/ext/deriving/zero.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{meta_item, item, expr}; +use ast::{MetaItem, item, expr}; use codemap::span; use ext::base::ExtCtxt; use ext::build::AstBuilder; @@ -18,7 +18,7 @@ use std::vec; pub fn expand_deriving_zero(cx: @ExtCtxt, span: span, - mitem: @meta_item, + mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 2f1d320fef7e6..e78254f11f5b8 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -14,6 +14,7 @@ use ast::{illegal_ctxt}; use ast; use ast_util::{new_rename, new_mark, resolve}; use attr; +use attr::AttrMetaMethods; use codemap; use codemap::{span, ExpnInfo, NameAndSpan}; use ext::base::*; @@ -126,7 +127,7 @@ pub fn expand_mod_items(extsbox: @mut SyntaxEnv, // the item into a new set of items. let new_items = do vec::flat_map(module_.items) |item| { do item.attrs.rev_iter().fold(~[*item]) |items, attr| { - let mname = attr::get_attr_name(attr); + let mname = attr.name(); match (*extsbox).find(&intern(mname)) { Some(@SE(ItemDecorator(dec_fn))) => { @@ -196,8 +197,8 @@ pub fn expand_item(extsbox: @mut SyntaxEnv, } // does this attribute list contain "macro_escape" ? -pub fn contains_macro_escape (attrs: &[ast::attribute]) -> bool { - attrs.iter().any(|attr| "macro_escape" == attr::get_attr_name(attr)) +pub fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool { + attr::contains_name(attrs, "macro_escape") } // Support for item-position macro invocations, exactly the same @@ -793,7 +794,7 @@ pub fn new_ident_resolver() -> mod test { use super::*; use ast; - use ast::{attribute_, attr_outer, meta_word, empty_ctxt}; + use ast::{Attribute_, AttrOuter, MetaWord, empty_ctxt}; use codemap; use codemap::spanned; use parse; @@ -883,14 +884,14 @@ mod test { assert_eq!(contains_macro_escape (attrs2),false); } - // make a "meta_word" outer attribute with the given name - fn make_dummy_attr(s: @str) -> ast::attribute { + // make a MetaWord outer attribute with the given name + fn make_dummy_attr(s: @str) -> ast::Attribute { spanned { span:codemap::dummy_sp(), - node: attribute_ { - style: attr_outer, + node: Attribute_ { + style: AttrOuter, value: @spanned { - node: meta_word(s), + node: MetaWord(s), span: codemap::dummy_sp(), }, is_sugared_doc: false, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index cfd858eed4716..63cb3cf38f698 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -74,35 +74,34 @@ pub type ast_fold_fns = @AstFoldFns; /* some little folds that probably aren't useful to have in ast_fold itself*/ //used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive -fn fold_meta_item_(mi: @meta_item, fld: @ast_fold) -> @meta_item { +fn fold_meta_item_(mi: @MetaItem, fld: @ast_fold) -> @MetaItem { @spanned { node: match mi.node { - meta_word(id) => meta_word(id), - meta_list(id, ref mis) => { + MetaWord(id) => MetaWord(id), + MetaList(id, ref mis) => { let fold_meta_item = |x| fold_meta_item_(x, fld); - meta_list( + MetaList( id, mis.map(|e| fold_meta_item(*e)) ) } - meta_name_value(id, s) => { - meta_name_value(id, s) - } + MetaNameValue(id, s) => MetaNameValue(id, s) }, span: fld.new_span(mi.span) } } //used in noop_fold_item and noop_fold_crate -fn fold_attribute_(at: attribute, fld: @ast_fold) -> attribute { +fn fold_attribute_(at: Attribute, fld: @ast_fold) -> Attribute { spanned { - node: ast::attribute_ { + span: fld.new_span(at.span), + node: ast::Attribute_ { style: at.node.style, value: fold_meta_item_(at.node.value, fld), - is_sugared_doc: at.node.is_sugared_doc, - }, - span: fld.new_span(at.span), + is_sugared_doc: at.node.is_sugared_doc + } } } + //used in noop_fold_foreign_item and noop_fold_fn_decl fn fold_arg_(a: arg, fld: @ast_fold) -> arg { ast::arg { @@ -936,11 +935,11 @@ impl ast_fold for AstFoldFns { } pub trait AstFoldExtensions { - fn fold_attributes(&self, attrs: ~[attribute]) -> ~[attribute]; + fn fold_attributes(&self, attrs: ~[Attribute]) -> ~[Attribute]; } impl AstFoldExtensions for @ast_fold { - fn fold_attributes(&self, attrs: ~[attribute]) -> ~[attribute] { + fn fold_attributes(&self, attrs: ~[Attribute]) -> ~[Attribute] { attrs.map(|x| fold_attribute_(*x, *self)) } } diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 85c7d5de06412..8cce5f15e67a8 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -17,32 +17,32 @@ use parse::parser::Parser; // a parser that can parse attributes. pub trait parser_attr { - fn parse_outer_attributes(&self) -> ~[ast::attribute]; - fn parse_attribute(&self, style: ast::attr_style) -> ast::attribute; + fn parse_outer_attributes(&self) -> ~[ast::Attribute]; + fn parse_attribute(&self, style: ast::AttrStyle) -> ast::Attribute; fn parse_attribute_naked( &self, - style: ast::attr_style, + style: ast::AttrStyle, lo: BytePos - ) -> ast::attribute; + ) -> ast::Attribute; fn parse_inner_attrs_and_next(&self) -> - (~[ast::attribute], ~[ast::attribute]); - fn parse_meta_item(&self) -> @ast::meta_item; - fn parse_meta_seq(&self) -> ~[@ast::meta_item]; - fn parse_optional_meta(&self) -> ~[@ast::meta_item]; + (~[ast::Attribute], ~[ast::Attribute]); + fn parse_meta_item(&self) -> @ast::MetaItem; + fn parse_meta_seq(&self) -> ~[@ast::MetaItem]; + fn parse_optional_meta(&self) -> ~[@ast::MetaItem]; } impl parser_attr for Parser { // Parse attributes that appear before an item - fn parse_outer_attributes(&self) -> ~[ast::attribute] { - let mut attrs: ~[ast::attribute] = ~[]; + fn parse_outer_attributes(&self) -> ~[ast::Attribute] { + let mut attrs: ~[ast::Attribute] = ~[]; loop { match *self.token { token::POUND => { if self.look_ahead(1, |t| *t != token::LBRACKET) { break; } - attrs.push(self.parse_attribute(ast::attr_outer)); + attrs.push(self.parse_attribute(ast::AttrOuter)); } token::DOC_COMMENT(s) => { let attr = ::attr::mk_sugared_doc_attr( @@ -50,7 +50,7 @@ impl parser_attr for Parser { self.span.lo, self.span.hi ); - if attr.node.style != ast::attr_outer { + if attr.node.style != ast::AttrOuter { self.fatal("expected outer comment"); } attrs.push(attr); @@ -63,20 +63,20 @@ impl parser_attr for Parser { } // matches attribute = # attribute_naked - fn parse_attribute(&self, style: ast::attr_style) -> ast::attribute { + fn parse_attribute(&self, style: ast::AttrStyle) -> ast::Attribute { let lo = self.span.lo; self.expect(&token::POUND); return self.parse_attribute_naked(style, lo); } // matches attribute_naked = [ meta_item ] - fn parse_attribute_naked(&self, style: ast::attr_style, lo: BytePos) -> - ast::attribute { + fn parse_attribute_naked(&self, style: ast::AttrStyle, lo: BytePos) -> + ast::Attribute { self.expect(&token::LBRACKET); let meta_item = self.parse_meta_item(); self.expect(&token::RBRACKET); let hi = self.span.hi; - return spanned(lo, hi, ast::attribute_ { style: style, + return spanned(lo, hi, ast::Attribute_ { style: style, value: meta_item, is_sugared_doc: false }); } // Parse attributes that appear after the opening of an item, each @@ -90,9 +90,9 @@ impl parser_attr for Parser { // you can make the 'next' field an Option, but the result is going to be // more useful as a vector. fn parse_inner_attrs_and_next(&self) -> - (~[ast::attribute], ~[ast::attribute]) { - let mut inner_attrs: ~[ast::attribute] = ~[]; - let mut next_outer_attrs: ~[ast::attribute] = ~[]; + (~[ast::Attribute], ~[ast::Attribute]) { + let mut inner_attrs: ~[ast::Attribute] = ~[]; + let mut next_outer_attrs: ~[ast::Attribute] = ~[]; loop { match *self.token { token::POUND => { @@ -100,7 +100,7 @@ impl parser_attr for Parser { // This is an extension break; } - let attr = self.parse_attribute(ast::attr_inner); + let attr = self.parse_attribute(ast::AttrInner); if *self.token == token::SEMI { self.bump(); inner_attrs.push(attr); @@ -108,7 +108,7 @@ impl parser_attr for Parser { // It's not really an inner attribute let outer_attr = spanned(attr.span.lo, attr.span.hi, - ast::attribute_ { style: ast::attr_outer, + ast::Attribute_ { style: ast::AttrOuter, value: attr.node.value, is_sugared_doc: false }); next_outer_attrs.push(outer_attr); @@ -122,7 +122,7 @@ impl parser_attr for Parser { self.span.hi ); self.bump(); - if attr.node.style == ast::attr_inner { + if attr.node.style == ast::AttrInner { inner_attrs.push(attr); } else { next_outer_attrs.push(attr); @@ -138,7 +138,7 @@ impl parser_attr for Parser { // matches meta_item = IDENT // | IDENT = lit // | IDENT meta_seq - fn parse_meta_item(&self) -> @ast::meta_item { + fn parse_meta_item(&self) -> @ast::MetaItem { let lo = self.span.lo; let name = self.id_to_str(self.parse_ident()); match *self.token { @@ -146,29 +146,29 @@ impl parser_attr for Parser { self.bump(); let lit = self.parse_lit(); let hi = self.span.hi; - @spanned(lo, hi, ast::meta_name_value(name, lit)) + @spanned(lo, hi, ast::MetaNameValue(name, lit)) } token::LPAREN => { let inner_items = self.parse_meta_seq(); let hi = self.span.hi; - @spanned(lo, hi, ast::meta_list(name, inner_items)) + @spanned(lo, hi, ast::MetaList(name, inner_items)) } _ => { let hi = self.last_span.hi; - @spanned(lo, hi, ast::meta_word(name)) + @spanned(lo, hi, ast::MetaWord(name)) } } } // matches meta_seq = ( COMMASEP(meta_item) ) - fn parse_meta_seq(&self) -> ~[@ast::meta_item] { + fn parse_meta_seq(&self) -> ~[@ast::MetaItem] { self.parse_seq(&token::LPAREN, &token::RPAREN, seq_sep_trailing_disallowed(token::COMMA), |p| p.parse_meta_item()).node } - fn parse_optional_meta(&self) -> ~[@ast::meta_item] { + fn parse_optional_meta(&self) -> ~[@ast::MetaItem] { match *self.token { token::LPAREN => self.parse_meta_seq(), _ => ~[] diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 83af5bade3a83..6daeb1b3e1e9e 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -44,12 +44,12 @@ pub fn is_doc_comment(s: &str) -> bool { s.starts_with("/*!") } -pub fn doc_comment_style(comment: &str) -> ast::attr_style { +pub fn doc_comment_style(comment: &str) -> ast::AttrStyle { assert!(is_doc_comment(comment)); if comment.starts_with("//!") || comment.starts_with("/*!") { - ast::attr_inner + ast::AttrInner } else { - ast::attr_outer + ast::AttrOuter } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 410849b448273..c7a65c80de18c 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -115,7 +115,7 @@ pub fn parse_item_from_source_str( name: @str, source: @str, cfg: ast::crate_cfg, - attrs: ~[ast::attribute], + attrs: ~[ast::Attribute], sess: @mut ParseSess ) -> Option<@ast::item> { let p = new_parser_from_source_str( @@ -132,7 +132,7 @@ pub fn parse_meta_from_source_str( source: @str, cfg: ast::crate_cfg, sess: @mut ParseSess -) -> @ast::meta_item { +) -> @ast::MetaItem { let p = new_parser_from_source_str( sess, cfg, @@ -146,7 +146,7 @@ pub fn parse_stmt_from_source_str( name: @str, source: @str, cfg: ast::crate_cfg, - attrs: ~[ast::attribute], + attrs: ~[ast::Attribute], sess: @mut ParseSess ) -> @ast::stmt { let p = new_parser_from_source_str( diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index b014c5668b675..6d7fd3390fa9b 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -17,7 +17,7 @@ Obsolete syntax that becomes too hard to parse can be removed. */ -use ast::{expr, expr_lit, lit_nil, attribute}; +use ast::{expr, expr_lit, lit_nil, Attribute}; use ast; use codemap::{span, respan}; use parse::parser::Parser; @@ -88,7 +88,7 @@ pub trait ParserObsoleteMethods { fn eat_obsolete_ident(&self, ident: &str) -> bool; fn try_parse_obsolete_struct_ctor(&self) -> bool; fn try_parse_obsolete_with(&self) -> bool; - fn try_parse_obsolete_priv_section(&self, attrs: &[attribute]) -> bool; + fn try_parse_obsolete_priv_section(&self, attrs: &[Attribute]) -> bool; } impl ParserObsoleteMethods for Parser { @@ -322,7 +322,7 @@ impl ParserObsoleteMethods for Parser { } } - pub fn try_parse_obsolete_priv_section(&self, attrs: &[attribute]) + pub fn try_parse_obsolete_priv_section(&self, attrs: &[Attribute]) -> bool { if self.is_keyword(keywords::Priv) && self.look_ahead(1, |t| *t == token::LBRACE) { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fb5d3b5262cf4..7e1d5bff4df2d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -15,7 +15,7 @@ use ast::{CallSugar, NoSugar, DoSugar, ForSugar}; use ast::{TyBareFn, TyClosure}; use ast::{RegionTyParamBound, TraitTyParamBound}; use ast::{provided, public, purity}; -use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer}; +use ast::{_mod, add, arg, arm, Attribute, bind_by_ref, bind_infer}; use ast::{bitand, bitor, bitxor, blk}; use ast::{blk_check_mode, box}; use ast::{crate, crate_cfg, decl, decl_item}; @@ -109,12 +109,12 @@ enum restriction { } type arg_or_capture_item = Either; -type item_info = (ident, item_, Option<~[attribute]>); +type item_info = (ident, item_, Option<~[Attribute]>); pub enum item_or_view_item { // Indicates a failure to parse any kind of item. The attributes are // returned. - iovi_none(~[attribute]), + iovi_none(~[Attribute]), iovi_item(@item), iovi_foreign_item(@foreign_item), iovi_view_item(view_item) @@ -242,8 +242,8 @@ macro_rules! maybe_whole ( ) -fn maybe_append(lhs: ~[attribute], rhs: Option<~[attribute]>) - -> ~[attribute] { +fn maybe_append(lhs: ~[Attribute], rhs: Option<~[Attribute]>) + -> ~[Attribute] { match rhs { None => lhs, Some(ref attrs) => vec::append(lhs, (*attrs)) @@ -252,7 +252,7 @@ fn maybe_append(lhs: ~[attribute], rhs: Option<~[attribute]>) struct ParsedItemsAndViewItems { - attrs_remaining: ~[attribute], + attrs_remaining: ~[Attribute], view_items: ~[view_item], items: ~[@item], foreign_items: ~[@foreign_item] @@ -2959,7 +2959,7 @@ impl Parser { // parse a structure field fn parse_name_and_ty(&self, pr: visibility, - attrs: ~[attribute]) -> @struct_field { + attrs: ~[Attribute]) -> @struct_field { let lo = self.span.lo; if !is_plain_ident(&*self.token) { self.fatal("expected ident"); @@ -2977,7 +2977,7 @@ impl Parser { // parse a statement. may include decl. // precondition: any attributes are parsed already - pub fn parse_stmt(&self, item_attrs: ~[attribute]) -> @stmt { + pub fn parse_stmt(&self, item_attrs: ~[Attribute]) -> @stmt { maybe_whole!(self, nt_stmt); fn check_expected_item(p: &Parser, found_attrs: bool) { @@ -3091,7 +3091,7 @@ impl Parser { // parse a block. Inner attrs are allowed. fn parse_inner_attrs_and_block(&self) - -> (~[attribute], blk) { + -> (~[Attribute], blk) { maybe_whole!(pair_empty self, nt_block); @@ -3115,7 +3115,7 @@ impl Parser { // parse the rest of a block expression or function body fn parse_block_tail_(&self, lo: BytePos, s: blk_check_mode, - first_item_attrs: ~[attribute]) -> blk { + first_item_attrs: ~[Attribute]) -> blk { let mut stmts = ~[]; let mut expr = None; @@ -3594,7 +3594,7 @@ impl Parser { fn mk_item(&self, lo: BytePos, hi: BytePos, ident: ident, node: item_, vis: visibility, - attrs: ~[attribute]) -> @item { + attrs: ~[Attribute]) -> @item { @ast::item { ident: ident, attrs: attrs, id: self.get_id(), @@ -3825,7 +3825,7 @@ impl Parser { // parse a structure field declaration pub fn parse_single_struct_field(&self, vis: visibility, - attrs: ~[attribute]) + attrs: ~[Attribute]) -> @struct_field { if self.eat_obsolete_ident("let") { self.obsolete(*self.last_span, ObsoleteLet); @@ -3894,7 +3894,7 @@ impl Parser { // attributes (of length 0 or 1), parse all of the items in a module fn parse_mod_items(&self, term: token::Token, - first_item_attrs: ~[attribute]) + first_item_attrs: ~[Attribute]) -> _mod { // parse all of the items up to closing or an attribute. // view items are legal here. @@ -3953,7 +3953,7 @@ impl Parser { } // parse a `mod { ... }` or `mod ;` item - fn parse_item_mod(&self, outer_attrs: &[ast::attribute]) -> item_info { + fn parse_item_mod(&self, outer_attrs: &[Attribute]) -> item_info { let id_span = *self.span; let id = self.parse_ident(); if *self.token == token::SEMI { @@ -3972,11 +3972,10 @@ impl Parser { } } - fn push_mod_path(&self, id: ident, attrs: &[ast::attribute]) { + fn push_mod_path(&self, id: ident, attrs: &[Attribute]) { let default_path = token::interner_get(id.name); - let file_path = match ::attr::first_attr_value_str_by_name( - attrs, "path") { - + let file_path = match ::attr::first_attr_value_str_by_name(attrs, + "path") { Some(d) => d, None => default_path }; @@ -3990,14 +3989,13 @@ impl Parser { // read a module from a source file. fn eval_src_mod(&self, id: ast::ident, - outer_attrs: &[ast::attribute], + outer_attrs: &[ast::Attribute], id_sp: span) - -> (ast::item_, ~[ast::attribute]) { + -> (ast::item_, ~[ast::Attribute]) { let prefix = Path(self.sess.cm.span_to_filename(*self.span)); let prefix = prefix.dir_path(); let mod_path_stack = &*self.mod_path_stack; let mod_path = Path(".").push_many(*mod_path_stack); - let default_path = token::interner_get(id.name).to_owned() + ".rs"; let file_path = match ::attr::first_attr_value_str_by_name( outer_attrs, "path") { Some(d) => { @@ -4008,7 +4006,7 @@ impl Parser { path } } - None => mod_path.push(default_path) + None => mod_path.push(token::interner_get(id.name) + ".rs") // default }; self.eval_src_mod_from_path(prefix, @@ -4020,8 +4018,8 @@ impl Parser { fn eval_src_mod_from_path(&self, prefix: Path, path: Path, - outer_attrs: ~[ast::attribute], - id_sp: span) -> (ast::item_, ~[ast::attribute]) { + outer_attrs: ~[ast::Attribute], + id_sp: span) -> (ast::item_, ~[ast::Attribute]) { let full_path = if path.is_absolute { path @@ -4057,17 +4055,10 @@ impl Parser { let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs); self.sess.included_mod_stack.pop(); return (ast::item_mod(m0), mod_attrs); - - fn cdir_path_opt(default: @str, attrs: ~[ast::attribute]) -> @str { - match ::attr::first_attr_value_str_by_name(attrs, "path") { - Some(d) => d, - None => default - } - } } // parse a function declaration from a foreign module - fn parse_item_foreign_fn(&self, attrs: ~[attribute]) -> @foreign_item { + fn parse_item_foreign_fn(&self, attrs: ~[Attribute]) -> @foreign_item { let lo = self.span.lo; let vis = self.parse_visibility(); let purity = self.parse_fn_purity(); @@ -4085,7 +4076,7 @@ impl Parser { // parse a const definition from a foreign module fn parse_item_foreign_const(&self, vis: ast::visibility, - attrs: ~[attribute]) -> @foreign_item { + attrs: ~[Attribute]) -> @foreign_item { let lo = self.span.lo; // XXX: Obsolete; remove after snap. @@ -4130,7 +4121,7 @@ impl Parser { fn parse_foreign_mod_items(&self, sort: ast::foreign_mod_sort, abis: AbiSet, - first_item_attrs: ~[attribute]) + first_item_attrs: ~[Attribute]) -> foreign_mod { let ParsedItemsAndViewItems { attrs_remaining: attrs_remaining, @@ -4156,7 +4147,7 @@ impl Parser { lo: BytePos, opt_abis: Option, visibility: visibility, - attrs: ~[attribute], + attrs: ~[Attribute], items_allowed: bool) -> item_or_view_item { let mut must_be_named_mod = false; @@ -4430,7 +4421,7 @@ impl Parser { // NB: this function no longer parses the items inside an // extern mod. fn parse_item_or_view_item(&self, - attrs: ~[attribute], + attrs: ~[Attribute], macros_allowed: bool) -> item_or_view_item { maybe_whole!(iovi self, nt_item); @@ -4562,7 +4553,7 @@ impl Parser { // parse a foreign item; on failure, return iovi_none. fn parse_foreign_item(&self, - attrs: ~[attribute], + attrs: ~[Attribute], macros_allowed: bool) -> item_or_view_item { maybe_whole!(iovi self, nt_item); @@ -4587,7 +4578,7 @@ impl Parser { // this is the fall-through for parsing items. fn parse_macro_use_or_failure( &self, - attrs: ~[attribute], + attrs: ~[Attribute], macros_allowed: bool, lo : BytePos, visibility : visibility @@ -4649,7 +4640,7 @@ impl Parser { return iovi_none(attrs); } - pub fn parse_item(&self, attrs: ~[attribute]) -> Option<@ast::item> { + pub fn parse_item(&self, attrs: ~[Attribute]) -> Option<@ast::item> { match self.parse_item_or_view_item(attrs, true) { iovi_none(_) => None, @@ -4786,7 +4777,7 @@ impl Parser { // parse a view item. fn parse_view_item( &self, - attrs: ~[attribute], + attrs: ~[Attribute], vis: visibility ) -> view_item { let lo = self.span.lo; @@ -4812,7 +4803,7 @@ impl Parser { // - mod_items uses extern_mod_allowed = true // - block_tail_ uses extern_mod_allowed = false fn parse_items_and_view_items(&self, - first_item_attrs: ~[attribute], + first_item_attrs: ~[Attribute], mut extern_mod_allowed: bool, macros_allowed: bool) -> ParsedItemsAndViewItems { @@ -4894,7 +4885,7 @@ impl Parser { // Parses a sequence of foreign items. Stops when it finds program // text that can't be parsed as an item - fn parse_foreign_items(&self, first_item_attrs: ~[attribute], + fn parse_foreign_items(&self, first_item_attrs: ~[Attribute], macros_allowed: bool) -> ParsedItemsAndViewItems { let mut attrs = vec::append(first_item_attrs, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index f14129948659a..42966edfc0b13 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -14,7 +14,7 @@ use ast; use ast_util; use opt_vec::OptVec; use opt_vec; -use attr; +use attr::{AttrMetaMethods, AttributeMethods}; use codemap::{CodeMap, BytePos}; use codemap; use diagnostic; @@ -212,11 +212,11 @@ pub fn block_to_str(blk: &ast::blk, intr: @ident_interner) -> ~str { } } -pub fn meta_item_to_str(mi: &ast::meta_item, intr: @ident_interner) -> ~str { +pub fn meta_item_to_str(mi: &ast::MetaItem, intr: @ident_interner) -> ~str { to_str(mi, print_meta_item, intr) } -pub fn attribute_to_str(attr: &ast::attribute, intr: @ident_interner) -> ~str { +pub fn attribute_to_str(attr: &ast::Attribute, intr: @ident_interner) -> ~str { to_str(attr, print_attribute, intr) } @@ -352,7 +352,7 @@ pub fn commasep_exprs(s: @ps, b: breaks, exprs: &[@ast::expr]) { commasep_cmnt(s, b, exprs, |p, &e| print_expr(p, e), |e| e.span); } -pub fn print_mod(s: @ps, _mod: &ast::_mod, attrs: &[ast::attribute]) { +pub fn print_mod(s: @ps, _mod: &ast::_mod, attrs: &[ast::Attribute]) { print_inner_attributes(s, attrs); for _mod.view_items.iter().advance |vitem| { print_view_item(s, vitem); @@ -361,7 +361,7 @@ pub fn print_mod(s: @ps, _mod: &ast::_mod, attrs: &[ast::attribute]) { } pub fn print_foreign_mod(s: @ps, nmod: &ast::foreign_mod, - attrs: &[ast::attribute]) { + attrs: &[ast::Attribute]) { print_inner_attributes(s, attrs); for nmod.view_items.iter().advance |vitem| { print_view_item(s, vitem); @@ -843,22 +843,22 @@ pub fn print_method(s: @ps, meth: &ast::method) { print_block_with_attrs(s, &meth.body, meth.attrs); } -pub fn print_outer_attributes(s: @ps, attrs: &[ast::attribute]) { +pub fn print_outer_attributes(s: @ps, attrs: &[ast::Attribute]) { let mut count = 0; for attrs.iter().advance |attr| { match attr.node.style { - ast::attr_outer => { print_attribute(s, attr); count += 1; } + ast::AttrOuter => { print_attribute(s, attr); count += 1; } _ => {/* fallthrough */ } } } if count > 0 { hardbreak_if_not_bol(s); } } -pub fn print_inner_attributes(s: @ps, attrs: &[ast::attribute]) { +pub fn print_inner_attributes(s: @ps, attrs: &[ast::Attribute]) { let mut count = 0; for attrs.iter().advance |attr| { match attr.node.style { - ast::attr_inner => { + ast::AttrInner => { print_attribute(s, attr); if !attr.node.is_sugared_doc { word(s.s, ";"); @@ -871,16 +871,15 @@ pub fn print_inner_attributes(s: @ps, attrs: &[ast::attribute]) { if count > 0 { hardbreak_if_not_bol(s); } } -pub fn print_attribute(s: @ps, attr: &ast::attribute) { +pub fn print_attribute(s: @ps, attr: &ast::Attribute) { hardbreak_if_not_bol(s); maybe_print_comment(s, attr.span.lo); if attr.node.is_sugared_doc { - let meta = attr::attr_meta(*attr); - let comment = attr::get_meta_item_value_str(meta).get(); + let comment = attr.value_str().get(); word(s.s, comment); } else { word(s.s, "#["); - print_meta_item(s, attr.node.value); + print_meta_item(s, attr.meta()); word(s.s, "]"); } } @@ -927,7 +926,7 @@ pub fn print_block_unclosed_indent(s: @ps, blk: &ast::blk, indented: uint) { pub fn print_block_with_attrs(s: @ps, blk: &ast::blk, - attrs: &[ast::attribute]) { + attrs: &[ast::Attribute]) { print_possibly_embedded_block_(s, blk, block_normal, indent_unit, attrs, true); } @@ -946,7 +945,7 @@ pub fn print_possibly_embedded_block_(s: @ps, blk: &ast::blk, embedded: embed_type, indented: uint, - attrs: &[ast::attribute], + attrs: &[ast::Attribute], close_box: bool) { match blk.rules { ast::unsafe_blk => word_space(s, "unsafe"), @@ -1793,16 +1792,16 @@ pub fn print_generics(s: @ps, generics: &ast::Generics) { } } -pub fn print_meta_item(s: @ps, item: &ast::meta_item) { +pub fn print_meta_item(s: @ps, item: &ast::MetaItem) { ibox(s, indent_unit); match item.node { - ast::meta_word(name) => word(s.s, name), - ast::meta_name_value(name, value) => { + ast::MetaWord(name) => word(s.s, name), + ast::MetaNameValue(name, value) => { word_space(s, name); word_space(s, "="); print_literal(s, @value); } - ast::meta_list(name, ref items) => { + ast::MetaList(name, ref items) => { word(s.s, name); popen(s); commasep(s,