Skip to content

Commit

Permalink
Rollup merge of #35850 - SergioBenitez:master, r=nrc
Browse files Browse the repository at this point in the history
Implement RFC#1559: allow all literals in attributes

Implemented rust-lang/rfcs#1559, tracked by #34981.
  • Loading branch information
jseyfried committed Aug 28, 2016
2 parents 6f074ba + 5d525ec commit ba876c2
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 19 deletions.
56 changes: 41 additions & 15 deletions clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ pub use self::Visibility::*;
use syntax::abi::Abi;
use syntax::ast;
use syntax::attr;
use syntax::attr::{AttributeMethods, AttrMetaMethods};
use syntax::attr::{AttributeMethods, AttrMetaMethods, AttrNestedMetaItemMethods};
use syntax::codemap::Spanned;
use syntax::parse::token::{self, InternedString, keywords};
use syntax::ptr::P;
use syntax::print::pprust as syntax_pprust;
use syntax_pos::{self, DUMMY_SP, Pos};

use rustc_trans::back::link;
Expand Down Expand Up @@ -501,11 +502,24 @@ impl Attributes for [Attribute] {
}
}

/// This is a flattened version of the AST's Attribute + MetaItem.
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
pub enum Attribute {
Word(String),
List(String, Vec<Attribute>),
NameValue(String, String)
NameValue(String, String),
Literal(String),
}

impl Clean<Attribute> for ast::NestedMetaItem {
fn clean(&self, cx: &DocContext) -> Attribute {
if let Some(mi) = self.meta_item() {
mi.clean(cx)
} else { // must be a literal
let lit = self.literal().unwrap();
Literal(syntax_pprust::lit_to_string(lit))
}
}
}

impl Clean<Attribute> for ast::MetaItem {
Expand All @@ -528,12 +542,28 @@ impl Clean<Attribute> for ast::Attribute {
}

// This is a rough approximation that gets us what we want.
impl attr::AttrMetaMethods for Attribute {
fn name(&self) -> InternedString {
impl attr::AttrNestedMetaItemMethods for Attribute {
fn check_name(&self, name: &str) -> bool {
self.name().map_or(false, |mi_name| &*mi_name == name)
}

fn literal(&self) -> Option<&ast::Lit> { None }

fn is_literal(&self) -> bool {
match *self {
Literal(..) => true,
_ => false,
}
}

fn meta_item(&self) -> Option<&P<ast::MetaItem>> { None }

fn name(&self) -> Option<InternedString> {
match *self {
Word(ref n) | List(ref n, _) | NameValue(ref n, _) => {
token::intern_and_get_ident(n)
}
Some(token::intern_and_get_ident(n))
},
_ => None
}
}

Expand All @@ -545,7 +575,8 @@ impl attr::AttrMetaMethods for Attribute {
_ => None,
}
}
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<ast::MetaItem>]> { None }

fn word(&self) -> Option<&P<ast::MetaItem>> { None }

fn is_word(&self) -> bool {
match *self {
Expand All @@ -554,12 +585,7 @@ impl attr::AttrMetaMethods for Attribute {
}
}

fn is_value_str(&self) -> bool {
match *self {
NameValue(..) => true,
_ => false,
}
}
fn meta_item_list<'a>(&'a self) -> Option<&'a [ast::NestedMetaItem]> { None }

fn is_meta_item_list(&self) -> bool {
match *self {
Expand Down Expand Up @@ -2534,8 +2560,8 @@ impl Clean<Vec<Item>> for doctree::Import {
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
let denied = self.vis != hir::Public || self.attrs.iter().any(|a| {
&a.name()[..] == "doc" && match a.meta_item_list() {
Some(l) => attr::contains_name(l, "no_inline") ||
attr::contains_name(l, "hidden"),
Some(l) => attr::list_contains_name(l, "no_inline") ||
attr::list_contains_name(l, "hidden"),
None => false,
}
});
Expand Down
3 changes: 2 additions & 1 deletion test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ pub fn run(input: &str,
// Look for #![doc(test(no_crate_inject))], used by crates in the std facade
fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
use syntax::attr::AttrMetaMethods;
use syntax::attr::AttrNestedMetaItemMethods;
use syntax::print::pprust;

let mut opts = TestOptions {
Expand All @@ -162,7 +163,7 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
if attr.check_name("attr") {
if let Some(l) = attr.meta_item_list() {
for item in l {
opts.attrs.push(pprust::meta_item_to_string(item));
opts.attrs.push(pprust::meta_list_item_to_string(item));
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions visit_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::mem;
use syntax::abi;
use syntax::ast;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::attr::{AttrMetaMethods, AttrNestedMetaItemMethods};
use syntax_pos::Span;

use rustc::hir::map as hir_map;
Expand Down Expand Up @@ -333,8 +333,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let node = if item.vis == hir::Public {
let please_inline = item.attrs.iter().any(|item| {
match item.meta_item_list() {
Some(list) if &item.name()[..] == "doc" => {
list.iter().any(|i| &i.name()[..] == "inline")
Some(list) if item.check_name("doc") => {
list.iter().any(|i| i.check_name("inline"))
}
_ => false,
}
Expand Down

0 comments on commit ba876c2

Please sign in to comment.