From cab73f88976da05f9d51202699eac86b66941a50 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 27 Jun 2011 23:02:02 -0700 Subject: [PATCH] Write metadata for more meta_item types. Issue #487 --- src/comp/back/link.rs | 26 ++++++++------- src/comp/front/ast.rs | 2 +- src/comp/front/fold.rs | 4 +-- src/comp/front/parser.rs | 2 +- src/comp/metadata/creader.rs | 15 ++++----- src/comp/metadata/decoder.rs | 48 ++++++++++++++++++---------- src/comp/metadata/encoder.rs | 28 ++++++++++++---- src/comp/metadata/tags.rs | 7 ++-- src/comp/pretty/pprust.rs | 16 ++++++---- src/test/run-pass/item-attributes.rs | 2 ++ 10 files changed, 95 insertions(+), 55 deletions(-) diff --git a/src/comp/back/link.rs b/src/comp/back/link.rs index e317ade1660..25c8b8b17d8 100644 --- a/src/comp/back/link.rs +++ b/src/comp/back/link.rs @@ -292,12 +292,10 @@ fn get_crate_meta_export(&session::session sess, &ast::crate c, str k, for each (@ast::meta_item mi in crate_export_metas(c)) { // FIXME (#487): Support all variants of meta_item alt (mi.node) { - case (ast::meta_key_value(?key, ?value)) { - if (key == k) { v += [mi]; } - } - case (_) { - sess.unimpl("meta_item variant"); + case (ast::meta_name_value(?name, ?value)) { + if (name == k) { v += [mi]; } } + case (_) {} } } alt (vec::len(v)) { @@ -310,11 +308,11 @@ fn get_crate_meta_export(&session::session sess, &ast::crate c, str k, } case (1u) { alt (v.(0).node) { - case (ast::meta_key_value(_, ?value)) { + case (ast::meta_name_value(_, ?value)) { ret value; } case (_) { - sess.unimpl("meta_item variant"); + ret default; } } } @@ -333,8 +331,11 @@ fn crate_meta_extras_hash(sha1 sha, &ast::crate crate) -> str { case (ast::meta_word(?name)) { name } - case (ast::meta_key_value(?key, _)) { - key + case (ast::meta_name_value(?name, _)) { + name + } + case (ast::meta_list(?name, _)) { + name } } } @@ -344,8 +345,8 @@ fn crate_meta_extras_hash(sha1 sha, &ast::crate crate) -> str { let vec[mutable @ast::meta_item] v = [mutable ]; for each (@ast::meta_item mi in crate_export_metas(crate)) { alt (mi.node) { - case (ast::meta_key_value(?key, _)) { - if (key != "name" && key != "vers") { + case (ast::meta_name_value(?name, _)) { + if (name != "name" && name != "vers") { v += [mutable mi]; } } @@ -359,13 +360,14 @@ fn crate_meta_extras_hash(sha1 sha, &ast::crate crate) -> str { for (@ast::meta_item m_ in v) { auto m = m_; alt (m.node) { - case (ast::meta_key_value(?key, ?value)) { + case (ast::meta_name_value(?key, ?value)) { sha.input_str(len_and_str(key)); sha.input_str(len_and_str(value)); } case (ast::meta_word(?name)) { sha.input_str(len_and_str(name)); } + case (_) {} } } ret truncated_sha1_result(sha); diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index c601d799214..abc1c11a44a 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -103,7 +103,7 @@ type meta_item = spanned[meta_item_]; tag meta_item_ { meta_word(ident); meta_list(ident, vec[@meta_item]); - meta_key_value(ident, str); + meta_name_value(ident, str); } type block = spanned[block_]; diff --git a/src/comp/front/fold.rs b/src/comp/front/fold.rs index fe0def71af1..d39c3060762 100644 --- a/src/comp/front/fold.rs +++ b/src/comp/front/fold.rs @@ -104,8 +104,8 @@ fn fold_meta_item_(&@meta_item mi, ast_fold fld) -> @meta_item { auto fold_meta_item = bind fold_meta_item_(_,fld); meta_list(id, map(fold_meta_item, mis)) } - case (meta_key_value(?id,?s)) { - meta_key_value(fld.fold_ident(id),s) + case (meta_name_value(?id,?s)) { + meta_name_value(fld.fold_ident(id),s) } }, span=mi.span); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 35db8495de0..801a02d6511 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -2142,7 +2142,7 @@ fn parse_meta_item(&parser p) -> @ast::meta_item { p.bump(); auto value = p.get_str(s); auto hi = p.get_hi_pos(); - ret @spanned(lo, hi, ast::meta_key_value(ident, value)); + ret @spanned(lo, hi, ast::meta_name_value(ident, value)); } case (_) { p.fatal("Metadata items must be string literals"); diff --git a/src/comp/metadata/creader.rs b/src/comp/metadata/creader.rs index 1bc2f685e5e..c2899e17953 100644 --- a/src/comp/metadata/creader.rs +++ b/src/comp/metadata/creader.rs @@ -30,22 +30,22 @@ fn metadata_matches(hashmap[str, str] mm, &vec[@ast::meta_item] metas) -> vec::len(metas), mm.size()); for (@ast::meta_item mi in metas) { alt (mi.node) { - case (ast::meta_key_value(?key, ?value)) { - alt (mm.find(key)) { + case (ast::meta_name_value(?name, ?value)) { + alt (mm.find(name)) { case (some(?v)) { if (v == value) { - log #fmt("matched '%s': '%s'", key, + log #fmt("matched '%s': '%s'", name, value); } else { log #fmt("missing '%s': '%s' (got '%s')", - key, + name, value, v); ret false; } } case (none) { log #fmt("missing '%s': '%s'", - key, value); + name, value); ret false; } } @@ -76,15 +76,14 @@ fn find_library_crate(&session::session sess, &ast::ident ident, let str crate_name = ident; for (@ast::meta_item mi in metas) { alt (mi.node) { - case (ast::meta_key_value(?key, ?value)) { - if (key == "name") { + case (ast::meta_name_value(?name, ?value)) { + if (name == "name") { crate_name = value; break; } } case (_) { // FIXME (#487) - sess.unimpl("meta_item variant") } } } diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index 500b3f31137..8a58a4ce319 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -256,16 +256,31 @@ 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 = []; +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_key_value)) { - auto kd = ebml::get_doc(meta_item_doc, tag_meta_item_key); + ebml::tagged_docs(md, tag_meta_item_word)) { + auto nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); + auto n = str::unsafe_from_bytes(ebml::doc_data(nd)); + items += [@rec(node=ast::meta_word(n), + span=rec(lo=0u, hi=0u))]; + } + for each (ebml::doc meta_item_doc in + ebml::tagged_docs(md, tag_meta_item_name_value)) { + auto nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); auto vd = ebml::get_doc(meta_item_doc, tag_meta_item_value); - auto k = str::unsafe_from_bytes(ebml::doc_data(kd)); + auto n = str::unsafe_from_bytes(ebml::doc_data(nd)); auto v = str::unsafe_from_bytes(ebml::doc_data(vd)); - items += [rec(node=ast::meta_key_value(k, v), - span=rec(lo=0u, hi=0u))]; + items += [@rec(node=ast::meta_name_value(n, v), + span=rec(lo=0u, hi=0u))]; + } + for each (ebml::doc meta_item_doc in + ebml::tagged_docs(md, tag_meta_item_list)) { + auto nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); + auto n = str::unsafe_from_bytes(ebml::doc_data(nd)); + auto subitems = get_meta_items(meta_item_doc); + items += [@rec(node=ast::meta_list(n, subitems), + span=rec(lo=0u, hi=0u))]; } ret items; } @@ -279,10 +294,11 @@ fn get_attributes(&ebml::doc md) -> vec[ast::attribute] { auto meta_items = get_meta_items(attr_doc); // Currently it's only possible to have a single meta item on // an attribute + log_err vec::len(meta_items); assert (vec::len(meta_items) == 1u); auto meta_item = meta_items.(0); attrs += [rec(node=rec(style=ast::attr_outer, - value=meta_item), + value=*meta_item), span=rec(lo=0u, hi=0u))]; } } @@ -292,8 +308,8 @@ fn get_attributes(&ebml::doc md) -> vec[ast::attribute] { } 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))); + for (@ast::meta_item mi in get_meta_items(meta_items)) { + out.write_str(#fmt("%s\n", pprust::meta_item_to_str(*mi))); } } @@ -345,14 +361,14 @@ 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_key_value)) { - auto kd = ebml::get_doc(m, tag_meta_item_key); + ebml::tagged_docs(meta_items, tag_meta_item_name_value)) { + auto nd = ebml::get_doc(m, tag_meta_item_name); auto vd = ebml::get_doc(m, tag_meta_item_value); - auto k = str::unsafe_from_bytes(ebml::doc_data(kd)); + auto n = str::unsafe_from_bytes(ebml::doc_data(nd)); auto v = str::unsafe_from_bytes(ebml::doc_data(vd)); - log #fmt("metadata in %s: %s = %s", path, k, v); - if (!mm.insert(k, v)) { - sess.warn(#fmt("Duplicate metadata item in %s: %s", path, k)); + log #fmt("metadata in %s: %s = %s", path, n, v); + if (!mm.insert(n, v)) { + sess.warn(#fmt("Duplicate metadata item in %s: %s", path, n)); } } ret mm; diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index da3b5bcb1b2..27a36e82675 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -418,21 +418,35 @@ fn write_int(&io::writer writer, &int n) { 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)); + case (meta_word(?name)) { + ebml::start_tag(ebml_w, tag_meta_item_word); + ebml::start_tag(ebml_w, tag_meta_item_name); + ebml_w.writer.write(str::bytes(name)); + ebml::end_tag(ebml_w); + ebml::end_tag(ebml_w); + } + case (meta_name_value(?name, ?value)) { + ebml::start_tag(ebml_w, tag_meta_item_name_value); + ebml::start_tag(ebml_w, tag_meta_item_name); + ebml_w.writer.write(str::bytes(name)); 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); + ebml::end_tag(ebml_w); } - case (_) { - log_err "unimplemented meta_item type"; + case (meta_list(?name, ?items)) { + ebml::start_tag(ebml_w, tag_meta_item_list); + ebml::start_tag(ebml_w, tag_meta_item_name); + ebml_w.writer.write(str::bytes(name)); + ebml::end_tag(ebml_w); + for (@meta_item inner_item in items) { + encode_meta_item(ebml_w, *inner_item); + } + ebml::end_tag(ebml_w); } } - ebml::end_tag(ebml_w); } fn encode_attributes(&ebml::writer ebml_w, &vec[attribute] attrs) { diff --git a/src/comp/metadata/tags.rs b/src/comp/metadata/tags.rs index 856023b0b90..43d7b3581ea 100644 --- a/src/comp/metadata/tags.rs +++ b/src/comp/metadata/tags.rs @@ -44,9 +44,9 @@ const uint tag_meta_export = 0x16u; const uint tag_meta_local = 0x17u; -const uint tag_meta_item_key_value = 0x18u; +const uint tag_meta_item_name_value = 0x18u; -const uint tag_meta_item_key = 0x19u; +const uint tag_meta_item_name = 0x19u; const uint tag_meta_item_value = 0x20u; @@ -54,3 +54,6 @@ const uint tag_attributes = 0x21u; const uint tag_attribute = 0x22u; +const uint tag_meta_item_word = 0x23u; + +const uint tag_meta_item_list = 0x24u; \ No newline at end of file diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs index a092dc86ddd..5d20a37e809 100644 --- a/src/comp/pretty/pprust.rs +++ b/src/comp/pretty/pprust.rs @@ -1062,16 +1062,20 @@ fn print_type_params(&ps s, &vec[ast::ty_param] params) { fn print_meta_item(&ps s, &@ast::meta_item item) { ibox(s, indent_unit); - // FIXME (#487): Print other meta item variants alt (item.node) { - case (ast::meta_key_value(?key, ?value)) { - word_space(s, key); + case (ast::meta_word(?name)) { + word(s.s, name); + } + case (ast::meta_name_value(?name, ?value)) { + word_space(s, name); word_space(s, "="); print_string(s, value); } - case (_) { - log_err "unimplemented meta_item variant"; - fail; + case (ast::meta_list(?name, ?items)) { + word(s.s, name); + popen(s); + commasep(s, consistent, items, print_meta_item); + pclose(s); } } end(s); diff --git a/src/test/run-pass/item-attributes.rs b/src/test/run-pass/item-attributes.rs index 35e578bf26c..bb8f068874c 100644 --- a/src/test/run-pass/item-attributes.rs +++ b/src/test/run-pass/item-attributes.rs @@ -5,6 +5,8 @@ // notation to specify their module's attributes #[attr1 = "val"]; #[attr2 = "val"]; +#[attr3]; +#[attr4(attr5)]; // These are are attributes of the following mod #[attr1 = "val"]