1
Fork 0

Redo exported macro serialization

The old method of serializing the AST gives totally bogus spans if the
expansion of an imported macro causes compilation errors. The best
solution seems to be to serialize the actual textual macro definition
and load it the same way the std-macros are. I'm not totally confident
that getting the source from the CodeMap will always do the right thing,
but it seems to work in simple cases.
This commit is contained in:
Steven Fackler 2014-01-21 23:09:53 -08:00
parent f8477c9da5
commit d908e97da3
10 changed files with 31 additions and 15 deletions

View file

@ -420,7 +420,7 @@ impl CrateLoader for Loader {
} }
} }
fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> ~[@ast::Item] { fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> ~[~str] {
csearch::get_exported_macros(self.env.sess.cstore, cnum) csearch::get_exported_macros(self.env.sess.cstore, cnum)
} }

View file

@ -310,7 +310,7 @@ pub fn get_macro_registrar_fn(cstore: @cstore::CStore,
pub fn get_exported_macros(cstore: @cstore::CStore, pub fn get_exported_macros(cstore: @cstore::CStore,
crate_num: ast::CrateNum) crate_num: ast::CrateNum)
-> ~[@ast::Item] { -> ~[~str] {
let cdata = cstore.get_crate_data(crate_num); let cdata = cstore.get_crate_data(crate_num);
decoder::get_exported_macros(cdata) decoder::get_exported_macros(cdata)
} }

View file

@ -23,7 +23,6 @@ use metadata::tydecode::{parse_ty_data, parse_def_id,
use middle::ty::{ImplContainer, TraitContainer}; use middle::ty::{ImplContainer, TraitContainer};
use middle::ty; use middle::ty;
use middle::typeck; use middle::typeck;
use middle::astencode;
use middle::astencode::vtable_decoder_helpers; use middle::astencode::vtable_decoder_helpers;
use std::at_vec; use std::at_vec;
@ -1282,12 +1281,12 @@ pub fn get_macro_registrar_fn(cdata: Cmd) -> Option<ast::DefId> {
.map(|doc| item_def_id(doc, cdata)) .map(|doc| item_def_id(doc, cdata))
} }
pub fn get_exported_macros(cdata: Cmd) -> ~[@ast::Item] { pub fn get_exported_macros(cdata: Cmd) -> ~[~str] {
let macros = reader::get_doc(reader::Doc(cdata.data()), let macros = reader::get_doc(reader::Doc(cdata.data()),
tag_exported_macros); tag_exported_macros);
let mut result = ~[]; let mut result = ~[];
reader::tagged_docs(macros, tag_macro_def, |macro_doc| { reader::tagged_docs(macros, tag_macro_def, |macro_doc| {
result.push(astencode::decode_exported_macro(macro_doc)); result.push(macro_doc.as_str());
true true
}); });
result result

View file

@ -37,6 +37,7 @@ use syntax::ast_map;
use syntax::ast_util::*; use syntax::ast_util::*;
use syntax::attr; use syntax::attr;
use syntax::attr::AttrMetaMethods; use syntax::attr::AttrMetaMethods;
use syntax::codemap;
use syntax::diagnostic::SpanHandler; use syntax::diagnostic::SpanHandler;
use syntax::parse::token::special_idents; use syntax::parse::token::special_idents;
use syntax::ast_util; use syntax::ast_util;
@ -71,6 +72,7 @@ pub struct EncodeParams<'a> {
cstore: @cstore::CStore, cstore: @cstore::CStore,
encode_inlined_item: encode_inlined_item<'a>, encode_inlined_item: encode_inlined_item<'a>,
reachable: @RefCell<HashSet<ast::NodeId>>, reachable: @RefCell<HashSet<ast::NodeId>>,
codemap: @codemap::CodeMap,
} }
struct Stats { struct Stats {
@ -101,6 +103,7 @@ pub struct EncodeContext<'a> {
encode_inlined_item: encode_inlined_item<'a>, encode_inlined_item: encode_inlined_item<'a>,
type_abbrevs: abbrev_map, type_abbrevs: abbrev_map,
reachable: @RefCell<HashSet<ast::NodeId>>, reachable: @RefCell<HashSet<ast::NodeId>>,
codemap: @codemap::CodeMap,
} }
pub fn reachable(ecx: &EncodeContext, id: NodeId) -> bool { pub fn reachable(ecx: &EncodeContext, id: NodeId) -> bool {
@ -1714,8 +1717,10 @@ impl<'a, 'b> Visitor<()> for MacroDefVisitor<'a, 'b> {
fn visit_item(&mut self, item: &Item, _: ()) { fn visit_item(&mut self, item: &Item, _: ()) {
match item.node { match item.node {
ItemMac(..) => { ItemMac(..) => {
let def = self.ecx.codemap.span_to_snippet(item.span)
.expect("Unable to find source for macro");
self.ebml_w.start_tag(tag_macro_def); self.ebml_w.start_tag(tag_macro_def);
astencode::encode_exported_macro(self.ebml_w, item); self.ebml_w.wr_str(def);
self.ebml_w.end_tag(); self.ebml_w.end_tag();
} }
_ => {} _ => {}
@ -1881,6 +1886,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, crate: &Crate)
link_meta, link_meta,
reachable, reachable,
non_inlineable_statics, non_inlineable_statics,
codemap,
.. ..
} = parms; } = parms;
let type_abbrevs = @RefCell::new(HashMap::new()); let type_abbrevs = @RefCell::new(HashMap::new());
@ -1897,6 +1903,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, crate: &Crate)
encode_inlined_item: encode_inlined_item, encode_inlined_item: encode_inlined_item,
type_abbrevs: type_abbrevs, type_abbrevs: type_abbrevs,
reachable: reachable, reachable: reachable,
codemap: codemap,
}; };
let mut ebml_w = writer::Encoder(wr); let mut ebml_w = writer::Encoder(wr);

View file

@ -2678,6 +2678,7 @@ pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::encode_
cstore: cx.sess.cstore, cstore: cx.sess.cstore,
encode_inlined_item: ie, encode_inlined_item: ie,
reachable: cx.reachable, reachable: cx.reachable,
codemap: cx.sess.codemap,
} }
} }

View file

@ -626,7 +626,7 @@ impl<'a> base::CrateLoader for CrateLoader<'a> {
self.loader.load_crate(crate) self.loader.load_crate(crate)
} }
fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> ~[@ast::Item] { fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> ~[~str] {
self.loader.get_exported_macros(cnum) self.loader.get_exported_macros(cnum)
} }

View file

@ -299,7 +299,7 @@ pub struct MacroCrate {
pub trait CrateLoader { pub trait CrateLoader {
fn load_crate(&mut self, crate: &ast::ViewItem) -> MacroCrate; fn load_crate(&mut self, crate: &ast::ViewItem) -> MacroCrate;
fn get_exported_macros(&mut self, crate_num: ast::CrateNum) -> ~[@ast::Item]; fn get_exported_macros(&mut self, crate_num: ast::CrateNum) -> ~[~str];
fn get_registrar_symbol(&mut self, crate_num: ast::CrateNum) -> Option<~str>; fn get_registrar_symbol(&mut self, crate_num: ast::CrateNum) -> Option<~str>;
} }

View file

@ -406,9 +406,20 @@ pub fn expand_view_item(vi: &ast::ViewItem,
fn load_extern_macros(crate: &ast::ViewItem, fld: &mut MacroExpander) { fn load_extern_macros(crate: &ast::ViewItem, fld: &mut MacroExpander) {
let MacroCrate { lib, cnum } = fld.cx.loader.load_crate(crate); let MacroCrate { lib, cnum } = fld.cx.loader.load_crate(crate);
let crate_name = match crate.node {
ast::ViewItemExternMod(ref name, _, _) => token::ident_to_str(name),
_ => unreachable!(),
};
let name = format!("<{} macros>", crate_name).to_managed();
let exported_macros = fld.cx.loader.get_exported_macros(cnum); let exported_macros = fld.cx.loader.get_exported_macros(cnum);
for &it in exported_macros.iter() { for source in exported_macros.iter() {
expand_item_mac(it, fld); let item = parse::parse_item_from_source_str(name,
source.to_managed(),
fld.cx.cfg(),
fld.cx.parse_sess())
.expect("expected a serialized item");
expand_item_mac(item, fld);
} }
let path = match lib { let path = match lib {
@ -944,7 +955,6 @@ pub fn inject_std_macros(parse_sess: @parse::ParseSess,
let sm = match parse_item_from_source_str(@"<std-macros>", let sm = match parse_item_from_source_str(@"<std-macros>",
std_macros(), std_macros(),
cfg.clone(), cfg.clone(),
~[],
parse_sess) { parse_sess) {
Some(item) => item, Some(item) => item,
None => fail!("expected core macros to parse correctly") None => fail!("expected core macros to parse correctly")
@ -1212,7 +1222,7 @@ mod test {
fail!("lolwut") fail!("lolwut")
} }
fn get_exported_macros(&mut self, _: ast::CrateNum) -> ~[@ast::Item] { fn get_exported_macros(&mut self, _: ast::CrateNum) -> ~[~str] {
fail!("lolwut") fail!("lolwut")
} }
@ -1289,7 +1299,7 @@ mod test {
let item_ast = parse::parse_item_from_source_str( let item_ast = parse::parse_item_from_source_str(
@"<test>", @"<test>",
src, src,
cfg,~[],sess); cfg,sess);
match item_ast { match item_ast {
Some(_) => (), // success Some(_) => (), // success
None => fail!("expected this to parse") None => fail!("expected this to parse")

View file

@ -250,7 +250,6 @@ pub mod rt {
@"<quote expansion>", @"<quote expansion>",
s, s,
self.cfg(), self.cfg(),
~[],
self.parse_sess()); self.parse_sess());
match res { match res {
Some(ast) => ast, Some(ast) => ast,

View file

@ -130,10 +130,10 @@ pub fn parse_item_from_source_str(
name: @str, name: @str,
source: @str, source: @str,
cfg: ast::CrateConfig, cfg: ast::CrateConfig,
attrs: ~[ast::Attribute],
sess: @ParseSess sess: @ParseSess
) -> Option<@ast::Item> { ) -> Option<@ast::Item> {
let mut p = new_parser_from_source_str(sess, cfg, name, source); let mut p = new_parser_from_source_str(sess, cfg, name, source);
let attrs = p.parse_outer_attributes();
maybe_aborted(p.parse_item(attrs),p) maybe_aborted(p.parse_item(attrs),p)
} }