Change std inject attributes to outer attributes

The #[phase(syntax,link)] attribute on `extern crate std` needs to be an
outer attribute so it can pretty-print properly.

Also add `#![no_std]` and `#[feature(phase)]` so compiling the
pretty-printed source will work.
This commit is contained in:
Kevin Ballard 2014-05-20 21:25:42 -07:00
parent e546452727
commit 23ca66ecd2
5 changed files with 48 additions and 28 deletions

View File

@ -22,6 +22,8 @@ use syntax::parse::token::InternedString;
use syntax::parse::token;
use syntax::util::small_vector::SmallVector;
use std::mem;
pub static VERSION: &'static str = "0.11.0-pre";
pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
@ -70,13 +72,13 @@ pub fn with_version(krate: &str) -> Option<(InternedString, ast::StrStyle)> {
}
impl<'a> fold::Folder for StandardLibraryInjector<'a> {
fn fold_crate(&mut self, krate: ast::Crate) -> ast::Crate {
fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
let mut vis = vec!(ast::ViewItem {
node: ast::ViewItemExternCrate(token::str_to_ident("std"),
with_version("std"),
ast::DUMMY_NODE_ID),
attrs: vec!(
attr::mk_attr(attr::mk_list_item(
attr::mk_attr_outer(attr::mk_list_item(
InternedString::new("phase"),
vec!(
attr::mk_word_item(InternedString::new("syntax")),
@ -101,16 +103,20 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
}
// `extern crate` must be precede `use` items
vis.push_all_move(krate.module.view_items.clone());
let new_module = ast::Mod {
view_items: vis,
..krate.module.clone()
};
mem::swap(&mut vis, &mut krate.module.view_items);
krate.module.view_items.push_all_move(vis);
ast::Crate {
module: new_module,
..krate
}
// don't add #![no_std] here, that will block the prelude injection later.
// 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(
InternedString::new("feature"),
vec![attr::mk_word_item(InternedString::new("phase"))],
));
krate.attrs.push(feat_phase_attr);
krate
}
}
@ -127,29 +133,29 @@ struct PreludeInjector<'a> {
impl<'a> fold::Folder for PreludeInjector<'a> {
fn fold_crate(&mut self, krate: ast::Crate) -> ast::Crate {
fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
// Add #![no_std] here, so we don't re-inject when compiling pretty-printed source.
// 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")));
krate.attrs.push(no_std_attr);
if !no_prelude(krate.attrs.as_slice()) {
// only add `use std::prelude::*;` if there wasn't a
// `#![no_implicit_prelude]` at the crate level.
let mut attrs = krate.attrs.clone();
// fold_mod() will insert glob path.
let globs_attr = attr::mk_attr(attr::mk_list_item(
let globs_attr = attr::mk_attr_inner(attr::mk_list_item(
InternedString::new("feature"),
vec!(
attr::mk_word_item(InternedString::new("globs")),
)));
attrs.push(globs_attr);
krate.attrs.push(globs_attr);
ast::Crate {
module: self.fold_mod(&krate.module),
attrs: attrs,
..krate
}
} else {
krate
krate.module = self.fold_mod(&krate.module);
}
krate
}
fn fold_item(&mut self, item: @ast::Item) -> SmallVector<@ast::Item> {

View File

@ -341,7 +341,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::Item {
// 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(attr::mk_word_item(resolve_unexported_str));
attr::mk_attr_inner(attr::mk_word_item(resolve_unexported_str));
let item = ast::Item {
ident: token::str_to_ident("__test"),

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(
attr::mk_attr_inner(
attr::mk_name_value_item_str(
InternedString::new("crate_id"),
token::intern_and_get_ident(ecx.link_meta.crateid.to_str())))

View File

@ -231,7 +231,7 @@ fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t,
let f = decl_rust_fn(ccx, false, inputs, output, name);
csearch::get_item_attrs(&ccx.sess().cstore, did, |meta_items| {
set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr(x))
set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr_outer(x))
.collect::<Vec<_>>().as_slice(), f)
});

View File

@ -126,7 +126,11 @@ impl AttributeMethods for Attribute {
InternedString::new("doc"),
token::intern_and_get_ident(strip_doc_comment_decoration(
comment.get()).as_slice()));
mk_attr(meta)
if self.node.style == ast::AttrOuter {
mk_attr_outer(meta)
} else {
mk_attr_inner(meta)
}
} else {
*self
}
@ -154,7 +158,8 @@ pub fn mk_word_item(name: InternedString) -> @MetaItem {
@dummy_spanned(MetaWord(name))
}
pub fn mk_attr(item: @MetaItem) -> Attribute {
/// Returns an inner attribute with the given value.
pub fn mk_attr_inner(item: @MetaItem) -> Attribute {
dummy_spanned(Attribute_ {
style: ast::AttrInner,
value: item,
@ -162,6 +167,15 @@ pub fn mk_attr(item: @MetaItem) -> Attribute {
})
}
/// Returns an outer attribute with the given value.
pub fn mk_attr_outer(item: @MetaItem) -> Attribute {
dummy_spanned(Attribute_ {
style: ast::AttrOuter,
value: item,
is_sugared_doc: false,
})
}
pub fn mk_sugared_doc_attr(text: InternedString, lo: BytePos, hi: BytePos)
-> Attribute {
let style = doc_comment_style(text.get());