Add AttrId to Attribute_

This commit is contained in:
Steven Fackler 2014-05-20 00:07:24 -07:00
parent 6304a27b80
commit c305473d3c
23 changed files with 94 additions and 30 deletions

View File

@ -91,7 +91,12 @@ pub fn calculate(krate: &ast::Crate) -> Svh {
// types and then use hash_content. But, since all crate
// attributes should appear near beginning of the file, it is
// not such a big deal to be sensitive to their spans for now.
krate.attrs.hash(&mut state);
//
// We hash only the MetaItems instead of the entire Attribute
// to avoid hashing the AttrId
for attr in krate.attrs.iter() {
attr.node.value.hash(&mut state);
}
let hash = state.result();
return Svh {

View File

@ -78,7 +78,7 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
with_version("std"),
ast::DUMMY_NODE_ID),
attrs: vec!(
attr::mk_attr_outer(attr::mk_list_item(
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
InternedString::new("phase"),
vec!(
attr::mk_word_item(InternedString::new("syntax")),
@ -110,7 +110,8 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
// Add it during the prelude injection instead.
// Add #![feature(phase)] here, because we use #[phase] on extern crate std.
let feat_phase_attr = attr::mk_attr_inner(attr::mk_list_item(
let feat_phase_attr = attr::mk_attr_inner(attr::mk_attr_id(),
attr::mk_list_item(
InternedString::new("feature"),
vec![attr::mk_word_item(InternedString::new("phase"))],
));
@ -138,7 +139,8 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
// This must happen here and not in StandardLibraryInjector because this
// fold happens second.
let no_std_attr = attr::mk_attr_inner(attr::mk_word_item(InternedString::new("no_std")));
let no_std_attr = attr::mk_attr_inner(attr::mk_attr_id(),
attr::mk_word_item(InternedString::new("no_std")));
krate.attrs.push(no_std_attr);
if !no_prelude(krate.attrs.as_slice()) {
@ -146,7 +148,8 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
// `#![no_implicit_prelude]` at the crate level.
// fold_mod() will insert glob path.
let globs_attr = attr::mk_attr_inner(attr::mk_list_item(
let globs_attr = attr::mk_attr_inner(attr::mk_attr_id(),
attr::mk_list_item(
InternedString::new("feature"),
vec!(
attr::mk_word_item(InternedString::new("globs")),

View File

@ -341,7 +341,8 @@ pub fn main() {
// This attribute tells resolve to let us call unexported functions
let resolve_unexported_str = InternedString::new("!resolve_unexported");
let resolve_unexported_attr =
attr::mk_attr_inner(attr::mk_word_item(resolve_unexported_str));
attr::mk_attr_inner(attr::mk_attr_id(),
attr::mk_word_item(resolve_unexported_str));
let item = ast::Item {
ident: token::str_to_ident("__test"),

View File

@ -1056,6 +1056,7 @@ fn get_attributes(md: ebml::Doc) -> Vec<ast::Attribute> {
attrs.push(
codemap::Spanned {
node: ast::Attribute_ {
id: attr::mk_attr_id(),
style: ast::AttrOuter,
value: meta_item,
is_sugared_doc: false,

View File

@ -1436,7 +1436,7 @@ fn synthesize_crate_attrs(ecx: &EncodeContext,
fn synthesize_crateid_attr(ecx: &EncodeContext) -> Attribute {
assert!(!ecx.link_meta.crateid.name.is_empty());
attr::mk_attr_inner(
attr::mk_attr_inner(attr::mk_attr_id(),
attr::mk_name_value_item_str(
InternedString::new("crate_id"),
token::intern_and_get_ident(ecx.link_meta

View File

@ -228,8 +228,9 @@ fn get_extern_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str, did: ast::De
let f = decl_rust_fn(ccx, fn_ty, name);
csearch::get_item_attrs(&ccx.sess().cstore, did, |meta_items| {
set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr_outer(x))
.collect::<Vec<_>>().as_slice(), f)
set_llvm_fn_attrs(meta_items.iter().map(|&x| {
attr::mk_attr_outer(attr::mk_attr_id(), x)
}).collect::<Vec<_>>().as_slice(), f)
});
ccx.externs.borrow_mut().insert(name.to_strbuf(), f);

View File

@ -1024,9 +1024,13 @@ pub enum AttrStyle {
AttrInner,
}
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
pub struct AttrId(pub uint);
// doc-comments are promoted to attributes that have is_sugared_doc = true
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
pub struct Attribute_ {
pub id: AttrId,
pub style: AttrStyle,
pub value: @MetaItem,
pub is_sugared_doc: bool,

View File

@ -11,7 +11,7 @@
// Functions dealing with attributes and meta items
use ast;
use ast::{Attribute, Attribute_, MetaItem, MetaWord, MetaNameValue, MetaList};
use ast::{AttrId, Attribute, Attribute_, MetaItem, MetaWord, MetaNameValue, MetaList};
use codemap::{Span, Spanned, spanned, dummy_spanned};
use codemap::BytePos;
use diagnostic::SpanHandler;
@ -22,6 +22,18 @@
use collections::HashSet;
local_data_key!(used_attrs: HashSet<AttrId>)
pub fn mark_used(attr: &Attribute) {
let mut used = used_attrs.replace(None).unwrap_or_else(|| HashSet::new());
used.insert(attr.node.id);
used_attrs.replace(Some(used));
}
pub fn is_used(attr: &Attribute) -> bool {
used_attrs.get().map_or(false, |used| used.contains(&attr.node.id))
}
pub trait AttrMetaMethods {
// This could be changed to `fn check_name(&self, name: InternedString) ->
// bool` which would facilitate a side table recording which
@ -127,9 +139,9 @@ fn desugar_doc(&self) -> Attribute {
token::intern_and_get_ident(strip_doc_comment_decoration(
comment.get()).as_slice()));
if self.node.style == ast::AttrOuter {
mk_attr_outer(meta)
mk_attr_outer(self.node.id, meta)
} else {
mk_attr_inner(meta)
mk_attr_inner(self.node.id, meta)
}
} else {
*self
@ -158,9 +170,18 @@ pub fn mk_word_item(name: InternedString) -> @MetaItem {
@dummy_spanned(MetaWord(name))
}
local_data_key!(next_attr_id: uint)
pub fn mk_attr_id() -> AttrId {
let id = next_attr_id.replace(None).unwrap_or(0);
next_attr_id.replace(Some(id + 1));
AttrId(id)
}
/// Returns an inner attribute with the given value.
pub fn mk_attr_inner(item: @MetaItem) -> Attribute {
pub fn mk_attr_inner(id: AttrId, item: @MetaItem) -> Attribute {
dummy_spanned(Attribute_ {
id: id,
style: ast::AttrInner,
value: item,
is_sugared_doc: false,
@ -168,19 +189,22 @@ pub fn mk_attr_inner(item: @MetaItem) -> Attribute {
}
/// Returns an outer attribute with the given value.
pub fn mk_attr_outer(item: @MetaItem) -> Attribute {
pub fn mk_attr_outer(id: AttrId, item: @MetaItem) -> Attribute {
dummy_spanned(Attribute_ {
id: id,
style: ast::AttrOuter,
value: item,
is_sugared_doc: false,
})
}
pub fn mk_sugared_doc_attr(text: InternedString, lo: BytePos, hi: BytePos)
pub fn mk_sugared_doc_attr(id: AttrId, text: InternedString, lo: BytePos,
hi: BytePos)
-> Attribute {
let style = doc_comment_style(text.get());
let lit = spanned(lo, hi, ast::LitStr(text, ast::CookedStr));
let attr = Attribute_ {
id: id,
style: style,
value: @spanned(lo, hi, MetaNameValue(InternedString::new("doc"),
lit)),

View File

@ -231,7 +231,7 @@ fn item_ty_poly(&self,
generics: Generics) -> @ast::Item;
fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item;
fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute;
fn attribute(&self, id: AttrId, sp: Span, mi: @ast::MetaItem) -> ast::Attribute;
fn meta_word(&self, sp: Span, w: InternedString) -> @ast::MetaItem;
fn meta_list(&self,
@ -925,8 +925,10 @@ fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> @ast::Item {
self.item_ty_poly(span, name, ty, ast_util::empty_generics())
}
fn attribute(&self, sp: Span, mi: @ast::MetaItem) -> ast::Attribute {
fn attribute(&self, id: ast::AttrId, sp: Span, mi: @ast::MetaItem)
-> ast::Attribute {
respan(sp, ast::Attribute_ {
id: id,
style: ast::AttrOuter,
value: mi,
is_sugared_doc: false,

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use attr;
use ast::{MetaItem, Item, Expr};
use codemap::Span;
use ext::base::ExtCtxt;
@ -21,7 +22,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt,
item: @Item,
push: |@Item|) {
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),

View File

@ -9,6 +9,7 @@
// except according to those terms.
use ast::{MetaItem, Item, Expr};
use attr;
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
@ -34,7 +35,7 @@ fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
macro_rules! md (
($name:expr, $f:ident) => { {
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
MethodDef {
name: $name,
generics: LifetimeBounds::empty(),

View File

@ -10,6 +10,7 @@
use ast;
use ast::{MetaItem, Item, Expr};
use attr;
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
@ -24,7 +25,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt,
macro_rules! md (
($name:expr, $op:expr, $equal:expr) => { {
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
MethodDef {
name: $name,
generics: LifetimeBounds::empty(),

View File

@ -9,6 +9,7 @@
// except according to those terms.
use ast::{MetaItem, Item, Expr};
use attr;
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
@ -37,8 +38,8 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> @E
let inline = cx.meta_word(span, InternedString::new("inline"));
let hidden = cx.meta_word(span, InternedString::new("hidden"));
let doc = cx.meta_list(span, InternedString::new("doc"), vec!(hidden));
let attrs = vec!(cx.attribute(span, inline),
cx.attribute(span, doc));
let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline),
cx.attribute(attr::mk_attr_id(), span, doc));
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),

View File

@ -10,6 +10,7 @@
use ast;
use ast::{MetaItem, Item, Expr};
use attr;
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
@ -24,7 +25,7 @@ pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
item: @Item,
push: |@Item|) {
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),

View File

@ -9,6 +9,7 @@
// except according to those terms.
use ast::{MetaItem, Item, Expr};
use attr;
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
@ -21,7 +22,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
item: @Item,
push: |@Item|) {
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),

View File

@ -182,6 +182,7 @@ fn eq(&self, other: &int) -> bool {
use ast;
use ast::{P, EnumDef, Expr, Ident, Generics, StructDef};
use ast_util;
use attr;
use attr::AttrMetaMethods;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
@ -427,6 +428,7 @@ fn create_derived_impl(&self,
self_ty_params.into_vec()), None);
let attr = cx.attribute(
attr::mk_attr_id(),
self.span,
cx.meta_word(self.span,
InternedString::new("automatically_derived")));

View File

@ -10,6 +10,7 @@
use ast;
use ast::{MetaItem, Item, Expr, MutMutable};
use attr;
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
@ -37,7 +38,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt,
Path::new(vec!("std", "hash", "sip", "SipState")))
};
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
let hash_trait_def = TraitDef {
span: span,
attributes: Vec::new(),

View File

@ -10,6 +10,7 @@
use ast::{MetaItem, Item, Expr};
use ast;
use attr;
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
@ -22,7 +23,7 @@ pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
item: @Item,
push: |@Item|) {
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),

View File

@ -9,6 +9,7 @@
// except according to those terms.
use ast::{MetaItem, Item, Expr};
use attr;
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
@ -21,7 +22,7 @@ pub fn expand_deriving_zero(cx: &mut ExtCtxt,
item: @Item,
push: |@Item|) {
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
let attrs = vec!(cx.attribute(attr::mk_attr_id(), span, inline));
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),

View File

@ -972,6 +972,7 @@ mod test {
use super::*;
use ast;
use ast::{Attribute_, AttrOuter, MetaWord};
use attr;
use codemap;
use codemap::Spanned;
use ext::base::{CrateLoader, MacroCrate};
@ -1103,6 +1104,7 @@ fn make_dummy_attr(s: &str) -> ast::Attribute {
Spanned {
span:codemap::DUMMY_SP,
node: Attribute_ {
id: attr::mk_attr_id(),
style: AttrOuter,
value: @Spanned {
node: MetaWord(token::intern_and_get_ident(s)),

View File

@ -10,6 +10,7 @@
use ast;
use ast::P;
use attr;
use codemap::{Span, respan};
use ext::base::*;
use ext::base;
@ -382,7 +383,8 @@ fn static_attrs(&self) -> Vec<ast::Attribute> {
.meta_word(self.fmtsp,
InternedString::new(
"address_insignificant"));
let unnamed = self.ecx.attribute(self.fmtsp, unnamed);
let unnamed = self.ecx.attribute(attr::mk_attr_id(), self.fmtsp,
unnamed);
// Do not warn format string as dead code
let dead_code = self.ecx.meta_word(self.fmtsp,
@ -390,7 +392,8 @@ fn static_attrs(&self) -> Vec<ast::Attribute> {
let allow_dead_code = self.ecx.meta_list(self.fmtsp,
InternedString::new("allow"),
vec!(dead_code));
let allow_dead_code = self.ecx.attribute(self.fmtsp, allow_dead_code);
let allow_dead_code = self.ecx.attribute(attr::mk_attr_id(), self.fmtsp,
allow_dead_code);
return vec!(unnamed, allow_dead_code);
}

View File

@ -360,6 +360,7 @@ fn fold_attribute_<T: Folder>(at: Attribute, fld: &mut T) -> Attribute {
Spanned {
span: fld.new_span(at.span),
node: ast::Attribute_ {
id: at.node.id,
style: at.node.style,
value: fold_meta_item_(at.node.value, fld),
is_sugared_doc: at.node.is_sugared_doc

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use attr;
use ast;
use codemap::{spanned, Spanned, mk_sp, Span};
use parse::common::*; //resolve bug?
@ -39,6 +40,7 @@ fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
}
token::DOC_COMMENT(s) => {
let attr = ::attr::mk_sugared_doc_attr(
attr::mk_attr_id(),
self.id_to_interned_str(s),
self.span.lo,
self.span.hi
@ -101,6 +103,7 @@ fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
return Spanned {
span: span,
node: ast::Attribute_ {
id: attr::mk_attr_id(),
style: style,
value: value,
is_sugared_doc: false
@ -132,7 +135,10 @@ fn parse_inner_attrs_and_next(&mut self)
// we need to get the position of this token before we bump.
let Span { lo, hi, .. } = self.span;
self.bump();
::attr::mk_sugared_doc_attr(self.id_to_interned_str(s), lo, hi)
::attr::mk_sugared_doc_attr(attr::mk_attr_id(),
self.id_to_interned_str(s),
lo,
hi)
}
_ => {
break;