diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index 1da65b97e34..500b3f31137 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -259,7 +259,7 @@ fn item_kind_to_str(u8 kind) -> str { fn get_meta_items(&ebml::doc md) -> vec[ast::meta_item] { let vec[ast::meta_item] items = []; for each (ebml::doc meta_item_doc in - ebml::tagged_docs(md, tag_meta_item)) { + ebml::tagged_docs(md, tag_meta_item_key_value)) { auto kd = ebml::get_doc(meta_item_doc, tag_meta_item_key); auto vd = ebml::get_doc(meta_item_doc, tag_meta_item_value); auto k = str::unsafe_from_bytes(ebml::doc_data(kd)); @@ -270,6 +270,27 @@ fn get_meta_items(&ebml::doc md) -> vec[ast::meta_item] { ret items; } +fn get_attributes(&ebml::doc md) -> vec[ast::attribute] { + let vec[ast::attribute] attrs = []; + alt (ebml::maybe_get_doc(md, tag_attributes)) { + case (option::some(?attrs_d)) { + for each (ebml::doc attr_doc in + ebml::tagged_docs(attrs_d, tag_attribute)) { + auto meta_items = get_meta_items(attr_doc); + // Currently it's only possible to have a single meta item on + // an attribute + assert (vec::len(meta_items) == 1u); + auto meta_item = meta_items.(0); + attrs += [rec(node=rec(style=ast::attr_outer, + value=meta_item), + span=rec(lo=0u, hi=0u))]; + } + } + case (option::none) { } + } + ret attrs; +} + fn list_meta_items(&ebml::doc meta_items, io::writer out) { for (ast::meta_item mi in get_meta_items(meta_items)) { out.write_str(#fmt("%s\n", pprust::meta_item_to_str(mi))); @@ -277,10 +298,18 @@ fn list_meta_items(&ebml::doc meta_items, io::writer out) { } fn list_crate_attributes(&ebml::doc md, io::writer out) { - out.write_str("=Crate=\n"); + out.write_str("=Crate="); + + // FIXME: This is transitional until attributes are snapshotted + out.write_str("old-style:\n"); auto meta_items = ebml::get_doc(md, tag_meta_export); list_meta_items(meta_items, out); - out.write_str("\n"); + + for (ast::attribute attr in get_attributes(md)) { + out.write_str(#fmt("%s", pprust::attribute_to_str(attr))); + } + + out.write_str("\n\n"); } fn list_crate_items(vec[u8] bytes, &ebml::doc md, io::writer out) { @@ -316,7 +345,7 @@ fn get_exported_metadata(&session::session sess, &str path, &vec[u8] data) -> ebml::get_doc(ebml::new_doc(data), tag_meta_export); auto mm = common::new_str_hash[str](); for each (ebml::doc m in - ebml::tagged_docs(meta_items, tag_meta_item)) { + ebml::tagged_docs(meta_items, tag_meta_item_key_value)) { auto kd = ebml::get_doc(m, tag_meta_item_key); auto vd = ebml::get_doc(m, tag_meta_item_value); auto k = str::unsafe_from_bytes(ebml::doc_data(kd)); diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index 3b74f79ab88..da3b5bcb1b2 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -416,25 +416,36 @@ fn write_int(&io::writer writer, &int n) { writer.write_be_uint(n as uint, 4u); } -fn encode_meta_items(&ebml::writer ebml_w, &crate crate) { - fn encode_meta_item(&ebml::writer ebml_w, &meta_item mi) { - // FIXME (#487): Support all forms of meta item - ebml::start_tag(ebml_w, tag_meta_item); - alt (mi.node) { - case (meta_key_value(?key, ?value)) { - ebml::start_tag(ebml_w, tag_meta_item_key); - ebml_w.writer.write(str::bytes(key)); - ebml::end_tag(ebml_w); - ebml::start_tag(ebml_w, tag_meta_item_value); - ebml_w.writer.write(str::bytes(value)); - ebml::end_tag(ebml_w); - } - case (_) { - log_err "unimplemented meta_item type"; - } +fn encode_meta_item(&ebml::writer ebml_w, &meta_item mi) { + // FIXME (#487): Support all forms of meta item + ebml::start_tag(ebml_w, tag_meta_item_key_value); + alt (mi.node) { + case (meta_key_value(?key, ?value)) { + ebml::start_tag(ebml_w, tag_meta_item_key); + ebml_w.writer.write(str::bytes(key)); + ebml::end_tag(ebml_w); + ebml::start_tag(ebml_w, tag_meta_item_value); + ebml_w.writer.write(str::bytes(value)); + ebml::end_tag(ebml_w); } + case (_) { + log_err "unimplemented meta_item type"; + } + } + ebml::end_tag(ebml_w); +} + +fn encode_attributes(&ebml::writer ebml_w, &vec[attribute] attrs) { + ebml::start_tag(ebml_w, tag_attributes); + for (attribute attr in attrs) { + ebml::start_tag(ebml_w, tag_attribute); + encode_meta_item(ebml_w, attr.node.value); ebml::end_tag(ebml_w); } + ebml::end_tag(ebml_w); +} + +fn encode_meta_items(&ebml::writer ebml_w, &crate crate) { ebml::start_tag(ebml_w, tag_meta_export); for each (@meta_item mi in crate_export_metas(crate)) { encode_meta_item(ebml_w, *mi); @@ -451,9 +462,12 @@ fn encode_metadata(&@crate_ctxt cx, &@crate crate) -> str { auto string_w = io::string_writer(); auto buf_w = string_w.get_writer().get_buf_writer(); auto ebml_w = ebml::create_writer(buf_w); - // Encode the meta items + // FIXME: This is the old way of encoding crate meta items + // Remove after going through a snapshot cycle encode_meta_items(ebml_w, *crate); + // Encode crate attributes + encode_attributes(ebml_w, crate.node.attrs); // Encode and index the paths. ebml::start_tag(ebml_w, tag_paths); diff --git a/src/comp/metadata/tags.rs b/src/comp/metadata/tags.rs index 9ce5a7947f5..856023b0b90 100644 --- a/src/comp/metadata/tags.rs +++ b/src/comp/metadata/tags.rs @@ -44,8 +44,13 @@ const uint tag_meta_export = 0x16u; const uint tag_meta_local = 0x17u; -const uint tag_meta_item = 0x18u; +const uint tag_meta_item_key_value = 0x18u; const uint tag_meta_item_key = 0x19u; const uint tag_meta_item_value = 0x20u; + +const uint tag_attributes = 0x21u; + +const uint tag_attribute = 0x22u; + diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs index 1e4d89cddcb..a092dc86ddd 100644 --- a/src/comp/pretty/pprust.rs +++ b/src/comp/pretty/pprust.rs @@ -84,6 +84,10 @@ fn meta_item_to_str(&ast::meta_item mi) -> str { ret to_str(@mi, print_meta_item); } +fn attribute_to_str(&ast::attribute attr) -> str { + be to_str(attr, print_attribute); +} + fn cbox(&ps s, uint u) { vec::push(s.boxes, pp::consistent); pp::cbox(s.s, u);