Change ast::meta_name_value to accept any literal, not just string

This isn't useful for much of anything yet, since metadata::encoder doesn't
know how to handle the non-string variants.

Issue #611
This commit is contained in:
Brian Anderson 2011-07-05 17:01:23 -07:00
parent 8261d2e6fb
commit 2cb129355b
10 changed files with 94 additions and 51 deletions

View file

@ -14,6 +14,7 @@ import std::sha1::sha1;
import std::sort; import std::sort;
import trans::crate_ctxt; import trans::crate_ctxt;
import syntax::ast; import syntax::ast;
import syntax::print::pprust;
import lib::llvm::llvm::ModuleRef; import lib::llvm::llvm::ModuleRef;
import lib::llvm::llvm::ValueRef; import lib::llvm::llvm::ValueRef;
import lib::llvm::mk_pass_manager; import lib::llvm::mk_pass_manager;
@ -294,16 +295,18 @@ fn build_link_meta(&session::session sess, &ast::crate c,
auto linkage_metas = attr::find_linkage_metas(c.node.attrs); auto linkage_metas = attr::find_linkage_metas(c.node.attrs);
attr::require_unique_names(sess, linkage_metas); attr::require_unique_names(sess, linkage_metas);
for (@ast::meta_item meta in linkage_metas) { for (@ast::meta_item meta in linkage_metas) {
alt (meta.node) { if (attr::get_meta_item_name(meta) == "name") {
case (ast::meta_name_value("name", ?v)) { alt (attr::get_meta_item_value_str(meta)) {
name = some(v); case (some(?v)) { name = some(v); }
case (none) { cmh_items += [meta]; }
} }
case (ast::meta_name_value("vers", ?v)) { } else if (attr::get_meta_item_name(meta) == "vers") {
vers = some(v); alt (attr::get_meta_item_value_str(meta)) {
} case (some(?v)) { vers = some(v); }
case (_) { case (none) { cmh_items += [meta]; }
cmh_items += [meta];
} }
} else {
cmh_items += [meta];
} }
} }
ret rec(name = name, ret rec(name = name,
@ -317,6 +320,10 @@ fn build_link_meta(&session::session sess, &ast::crate c,
fn len_and_str(&str s) -> str { fn len_and_str(&str s) -> str {
ret #fmt("%u_%s", str::byte_len(s), s); ret #fmt("%u_%s", str::byte_len(s), s);
} }
fn len_and_str_lit(&ast::lit l) -> str {
ret len_and_str(pprust::lit_to_str(@l));
}
auto cmh_items = attr::sort_meta_items(metas.cmh_items); auto cmh_items = attr::sort_meta_items(metas.cmh_items);
@ -326,7 +333,7 @@ fn build_link_meta(&session::session sess, &ast::crate c,
alt (m.node) { alt (m.node) {
case (ast::meta_name_value(?key, ?value)) { case (ast::meta_name_value(?key, ?value)) {
sha.input_str(len_and_str(key)); sha.input_str(len_and_str(key));
sha.input_str(len_and_str(value)); sha.input_str(len_and_str_lit(value));
} }
case (ast::meta_word(?name)) { case (ast::meta_word(?name)) {
sha.input_str(len_and_str(name)); sha.input_str(len_and_str(name));

View file

@ -48,7 +48,7 @@ fn default_configuration(session::session sess, str argv0, str input) ->
case (_) { "libc.so" } case (_) { "libc.so" }
}; };
auto mk = attr::mk_name_value_item; auto mk = attr::mk_name_value_item_str;
ret [ // Target bindings. ret [ // Target bindings.
mk("target_os", std::os::target_os()), mk("target_os", std::os::target_os()),

View file

@ -8,6 +8,7 @@ import syntax::ast;
import util::common; import util::common;
import driver::session; import driver::session;
export attr_meta;
export attr_metas; export attr_metas;
export find_linkage_metas; export find_linkage_metas;
export find_attrs_by_name; export find_attrs_by_name;
@ -17,6 +18,9 @@ export sort_meta_items;
export remove_meta_items_by_name; export remove_meta_items_by_name;
export require_unique_names; export require_unique_names;
export get_attr_name; export get_attr_name;
export get_meta_item_name;
export get_meta_item_value_str;
export mk_name_value_item_str;
export mk_name_value_item; export mk_name_value_item;
export mk_list_item; export mk_list_item;
export mk_word_item; export mk_word_item;
@ -78,9 +82,25 @@ fn get_meta_item_name(&@ast::meta_item meta) -> ast::ident {
} }
} }
// Gets the string value if the meta_item is a meta_name_value variant
// containing a string, otherwise none
fn get_meta_item_value_str(&@ast::meta_item meta) -> option::t[str] {
alt (meta.node) {
case (ast::meta_name_value(_, ?v)) {
alt (v.node) {
case (ast::lit_str(?s, _)) {
option::some(s)
}
case (_) { option::none }
}
}
case (_) { option::none }
}
}
fn attr_meta(&ast::attribute attr) -> @ast::meta_item { @attr.node.value } fn attr_meta(&ast::attribute attr) -> @ast::meta_item { @attr.node.value }
// Get the meta_items from inside an attribute // Get the meta_items from inside a vector of attributes
fn attr_metas(&vec[ast::attribute] attrs) -> vec[@ast::meta_item] { fn attr_metas(&vec[ast::attribute] attrs) -> vec[@ast::meta_item] {
ret vec::map(attr_meta, attrs); ret vec::map(attr_meta, attrs);
} }
@ -95,7 +115,9 @@ fn eq(@ast::meta_item a, @ast::meta_item b) -> bool {
} }
case (ast::meta_name_value(?na, ?va)) { case (ast::meta_name_value(?na, ?va)) {
alt (b.node) { alt (b.node) {
case (ast::meta_name_value(?nb, ?vb)) { na == nb && va == vb } case (ast::meta_name_value(?nb, ?vb)) {
na == nb && va.node == vb.node
}
case (_) { false } case (_) { false }
} }
} }
@ -188,7 +210,12 @@ fn span[T](&T item) -> ast::spanned[T] {
ret rec(node=item, span=rec(lo=0u, hi=0u)); ret rec(node=item, span=rec(lo=0u, hi=0u));
} }
fn mk_name_value_item(ast::ident name, str value) -> @ast::meta_item { fn mk_name_value_item_str(ast::ident name, str value) -> @ast::meta_item {
auto value_lit = span(ast::lit_str(value, ast::sk_rc));
ret mk_name_value_item(name, value_lit);
}
fn mk_name_value_item(ast::ident name, ast::lit value) -> @ast::meta_item {
ret @span(ast::meta_name_value(name, value)); ret @span(ast::meta_name_value(name, value));
} }

View file

@ -64,8 +64,8 @@ fn find_library_crate(&session::session sess, &ast::ident ident,
auto name_items = attr::find_meta_items_by_name(metas, "name"); auto name_items = attr::find_meta_items_by_name(metas, "name");
alt (vec::last(name_items)) { alt (vec::last(name_items)) {
case (some(?i)) { case (some(?i)) {
alt (i.node) { alt (attr::get_meta_item_value_str(i)) {
case (ast::meta_name_value(_, ?v)) { v } case (some(?n)) { n }
case (_) { case (_) {
// FIXME: Probably want a warning here since the user // FIXME: Probably want a warning here since the user
// is using the wrong type of meta item // is using the wrong type of meta item
@ -180,17 +180,13 @@ fn visit_item(env e, &@ast::item i) {
if (!e.sess.add_used_library(m.native_name)) { if (!e.sess.add_used_library(m.native_name)) {
ret; ret;
} }
for (ast::attribute a in i.attrs) { for (ast::attribute a in
auto v = a.node.value.node; attr::find_attrs_by_name(i.attrs, "link_args")) {
alt (v) { alt (attr::get_meta_item_value_str(attr::attr_meta(a))) {
case (ast::meta_name_value(?i, ?s)) { case (some(?linkarg)) {
if (i != "link_args") { e.sess.add_used_link_args(linkarg);
cont;
}
e.sess.add_used_link_args(s);
}
case (_) {
} }
case (none) { /* fallthrough */ }
} }
} }
} }

View file

@ -276,7 +276,9 @@ fn get_meta_items(&ebml::doc md) -> vec[@ast::meta_item] {
auto vd = ebml::get_doc(meta_item_doc, tag_meta_item_value); auto vd = ebml::get_doc(meta_item_doc, tag_meta_item_value);
auto n = str::unsafe_from_bytes(ebml::doc_data(nd)); auto n = str::unsafe_from_bytes(ebml::doc_data(nd));
auto v = str::unsafe_from_bytes(ebml::doc_data(vd)); auto v = str::unsafe_from_bytes(ebml::doc_data(vd));
items += [attr::mk_name_value_item(n, v)]; // FIXME (#611): Should be able to decode meta_name_value variants,
// but currently they can't be encoded
items += [attr::mk_name_value_item_str(n, v)];
} }
for each (ebml::doc meta_item_doc in for each (ebml::doc meta_item_doc in
ebml::tagged_docs(md, tag_meta_item_list)) { ebml::tagged_docs(md, tag_meta_item_list)) {

View file

@ -429,14 +429,19 @@ fn encode_meta_item(&ebml::writer ebml_w, &meta_item mi) {
ebml::end_tag(ebml_w); ebml::end_tag(ebml_w);
} }
case (meta_name_value(?name, ?value)) { case (meta_name_value(?name, ?value)) {
ebml::start_tag(ebml_w, tag_meta_item_name_value); alt (value.node) {
ebml::start_tag(ebml_w, tag_meta_item_name); case (lit_str(?value, _)) {
ebml_w.writer.write(str::bytes(name)); ebml::start_tag(ebml_w, tag_meta_item_name_value);
ebml::end_tag(ebml_w); ebml::start_tag(ebml_w, tag_meta_item_name);
ebml::start_tag(ebml_w, tag_meta_item_value); ebml_w.writer.write(str::bytes(name));
ebml_w.writer.write(str::bytes(value)); ebml::end_tag(ebml_w);
ebml::end_tag(ebml_w); ebml::start_tag(ebml_w, tag_meta_item_value);
ebml::end_tag(ebml_w); ebml_w.writer.write(str::bytes(value));
ebml::end_tag(ebml_w);
ebml::end_tag(ebml_w);
}
case (_) { /* FIXME (#611) */ }
}
} }
case (meta_list(?name, ?items)) { case (meta_list(?name, ?items)) {
ebml::start_tag(ebml_w, tag_meta_item_list); ebml::start_tag(ebml_w, tag_meta_item_list);
@ -475,10 +480,10 @@ fn synthesize_crate_attrs(&@crate_ctxt cx,
assert cx.link_meta.name != ""; assert cx.link_meta.name != "";
assert cx.link_meta.vers != ""; assert cx.link_meta.vers != "";
auto name_item = attr::mk_name_value_item("name", auto name_item = attr::mk_name_value_item_str("name",
cx.link_meta.name); cx.link_meta.name);
auto vers_item = attr::mk_name_value_item("vers", auto vers_item = attr::mk_name_value_item_str("vers",
cx.link_meta.vers); cx.link_meta.vers);
auto other_items = { auto other_items = {
auto tmp = attr::remove_meta_items_by_name(items, "name"); auto tmp = attr::remove_meta_items_by_name(items, "name");

View file

@ -104,7 +104,7 @@ type meta_item = spanned[meta_item_];
tag meta_item_ { tag meta_item_ {
meta_word(ident); meta_word(ident);
meta_list(ident, vec[@meta_item]); meta_list(ident, vec[@meta_item]);
meta_name_value(ident, str); meta_name_value(ident, lit);
} }
type block = spanned[block_]; type block = spanned[block_];

View file

@ -2172,17 +2172,9 @@ fn parse_meta_item(&parser p) -> @ast::meta_item {
alt (p.peek()) { alt (p.peek()) {
case (token::EQ) { case (token::EQ) {
p.bump(); p.bump();
alt (p.peek()) { auto lit = parse_lit(p);
case (token::LIT_STR(?s)) { auto hi = p.get_hi_pos();
p.bump(); ret @spanned(lo, hi, ast::meta_name_value(ident, lit));
auto value = p.get_str(s);
auto hi = p.get_hi_pos();
ret @spanned(lo, hi, ast::meta_name_value(ident, value));
}
case (_) {
p.fatal("Metadata items must be string literals");
}
}
} }
case (token::LPAREN) { case (token::LPAREN) {
auto inner_items = parse_meta_seq(p); auto inner_items = parse_meta_seq(p);

View file

@ -1103,7 +1103,7 @@ fn print_meta_item(&ps s, &@ast::meta_item item) {
case (ast::meta_name_value(?name, ?value)) { case (ast::meta_name_value(?name, ?value)) {
word_space(s, name); word_space(s, name);
word_space(s, "="); word_space(s, "=");
print_string(s, value); print_literal(s, @value);
} }
case (ast::meta_list(?name, ?items)) { case (ast::meta_list(?name, ?items)) {
word(s.s, name); word(s.s, name);

View file

@ -204,6 +204,20 @@ mod test_native_items {
} }
} }
mod test_literals {
#[str = "s"];
#[char = 'c'];
#[int = 100];
#[uint = 100u];
#[mach_int = 100u32];
#[float = 1.0];
#[mach_float = 1.0f32];
// FIXME (#622): Can't parse a nil literal here
//#[nil = ()];
#[bool = true];
mod m {}
}
fn main() { fn main() {
} }