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:
parent
8261d2e6fb
commit
2cb129355b
10 changed files with 94 additions and 51 deletions
|
@ -14,6 +14,7 @@ import std::sha1::sha1;
|
|||
import std::sort;
|
||||
import trans::crate_ctxt;
|
||||
import syntax::ast;
|
||||
import syntax::print::pprust;
|
||||
import lib::llvm::llvm::ModuleRef;
|
||||
import lib::llvm::llvm::ValueRef;
|
||||
import lib::llvm::mk_pass_manager;
|
||||
|
@ -294,18 +295,20 @@ fn build_link_meta(&session::session sess, &ast::crate c,
|
|||
auto linkage_metas = attr::find_linkage_metas(c.node.attrs);
|
||||
attr::require_unique_names(sess, linkage_metas);
|
||||
for (@ast::meta_item meta in linkage_metas) {
|
||||
alt (meta.node) {
|
||||
case (ast::meta_name_value("name", ?v)) {
|
||||
name = some(v);
|
||||
if (attr::get_meta_item_name(meta) == "name") {
|
||||
alt (attr::get_meta_item_value_str(meta)) {
|
||||
case (some(?v)) { name = some(v); }
|
||||
case (none) { cmh_items += [meta]; }
|
||||
}
|
||||
case (ast::meta_name_value("vers", ?v)) {
|
||||
vers = some(v);
|
||||
} else if (attr::get_meta_item_name(meta) == "vers") {
|
||||
alt (attr::get_meta_item_value_str(meta)) {
|
||||
case (some(?v)) { vers = some(v); }
|
||||
case (none) { cmh_items += [meta]; }
|
||||
}
|
||||
case (_) {
|
||||
} else {
|
||||
cmh_items += [meta];
|
||||
}
|
||||
}
|
||||
}
|
||||
ret rec(name = name,
|
||||
vers = vers,
|
||||
cmh_items = cmh_items);
|
||||
|
@ -318,6 +321,10 @@ fn build_link_meta(&session::session sess, &ast::crate c,
|
|||
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);
|
||||
|
||||
sha.reset();
|
||||
|
@ -326,7 +333,7 @@ fn build_link_meta(&session::session sess, &ast::crate c,
|
|||
alt (m.node) {
|
||||
case (ast::meta_name_value(?key, ?value)) {
|
||||
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)) {
|
||||
sha.input_str(len_and_str(name));
|
||||
|
|
|
@ -48,7 +48,7 @@ fn default_configuration(session::session sess, str argv0, str input) ->
|
|||
case (_) { "libc.so" }
|
||||
};
|
||||
|
||||
auto mk = attr::mk_name_value_item;
|
||||
auto mk = attr::mk_name_value_item_str;
|
||||
|
||||
ret [ // Target bindings.
|
||||
mk("target_os", std::os::target_os()),
|
||||
|
|
|
@ -8,6 +8,7 @@ import syntax::ast;
|
|||
import util::common;
|
||||
import driver::session;
|
||||
|
||||
export attr_meta;
|
||||
export attr_metas;
|
||||
export find_linkage_metas;
|
||||
export find_attrs_by_name;
|
||||
|
@ -17,6 +18,9 @@ export sort_meta_items;
|
|||
export remove_meta_items_by_name;
|
||||
export require_unique_names;
|
||||
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_list_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 }
|
||||
|
||||
// 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] {
|
||||
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)) {
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +210,12 @@ fn span[T](&T item) -> ast::spanned[T] {
|
|||
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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
alt (vec::last(name_items)) {
|
||||
case (some(?i)) {
|
||||
alt (i.node) {
|
||||
case (ast::meta_name_value(_, ?v)) { v }
|
||||
alt (attr::get_meta_item_value_str(i)) {
|
||||
case (some(?n)) { n }
|
||||
case (_) {
|
||||
// FIXME: Probably want a warning here since the user
|
||||
// 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)) {
|
||||
ret;
|
||||
}
|
||||
for (ast::attribute a in i.attrs) {
|
||||
auto v = a.node.value.node;
|
||||
alt (v) {
|
||||
case (ast::meta_name_value(?i, ?s)) {
|
||||
if (i != "link_args") {
|
||||
cont;
|
||||
}
|
||||
e.sess.add_used_link_args(s);
|
||||
}
|
||||
case (_) {
|
||||
for (ast::attribute a in
|
||||
attr::find_attrs_by_name(i.attrs, "link_args")) {
|
||||
alt (attr::get_meta_item_value_str(attr::attr_meta(a))) {
|
||||
case (some(?linkarg)) {
|
||||
e.sess.add_used_link_args(linkarg);
|
||||
}
|
||||
case (none) { /* fallthrough */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 n = str::unsafe_from_bytes(ebml::doc_data(nd));
|
||||
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
|
||||
ebml::tagged_docs(md, tag_meta_item_list)) {
|
||||
|
|
|
@ -429,6 +429,8 @@ fn encode_meta_item(&ebml::writer ebml_w, &meta_item mi) {
|
|||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
case (meta_name_value(?name, ?value)) {
|
||||
alt (value.node) {
|
||||
case (lit_str(?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));
|
||||
|
@ -438,6 +440,9 @@ fn encode_meta_item(&ebml::writer ebml_w, &meta_item mi) {
|
|||
ebml::end_tag(ebml_w);
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
case (_) { /* FIXME (#611) */ }
|
||||
}
|
||||
}
|
||||
case (meta_list(?name, ?items)) {
|
||||
ebml::start_tag(ebml_w, tag_meta_item_list);
|
||||
ebml::start_tag(ebml_w, tag_meta_item_name);
|
||||
|
@ -475,9 +480,9 @@ fn synthesize_crate_attrs(&@crate_ctxt cx,
|
|||
assert cx.link_meta.name != "";
|
||||
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);
|
||||
auto vers_item = attr::mk_name_value_item("vers",
|
||||
auto vers_item = attr::mk_name_value_item_str("vers",
|
||||
cx.link_meta.vers);
|
||||
|
||||
auto other_items = {
|
||||
|
|
|
@ -104,7 +104,7 @@ type meta_item = spanned[meta_item_];
|
|||
tag meta_item_ {
|
||||
meta_word(ident);
|
||||
meta_list(ident, vec[@meta_item]);
|
||||
meta_name_value(ident, str);
|
||||
meta_name_value(ident, lit);
|
||||
}
|
||||
|
||||
type block = spanned[block_];
|
||||
|
|
|
@ -2172,17 +2172,9 @@ fn parse_meta_item(&parser p) -> @ast::meta_item {
|
|||
alt (p.peek()) {
|
||||
case (token::EQ) {
|
||||
p.bump();
|
||||
alt (p.peek()) {
|
||||
case (token::LIT_STR(?s)) {
|
||||
p.bump();
|
||||
auto value = p.get_str(s);
|
||||
auto lit = parse_lit(p);
|
||||
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");
|
||||
}
|
||||
}
|
||||
ret @spanned(lo, hi, ast::meta_name_value(ident, lit));
|
||||
}
|
||||
case (token::LPAREN) {
|
||||
auto inner_items = parse_meta_seq(p);
|
||||
|
|
|
@ -1103,7 +1103,7 @@ fn print_meta_item(&ps s, &@ast::meta_item item) {
|
|||
case (ast::meta_name_value(?name, ?value)) {
|
||||
word_space(s, name);
|
||||
word_space(s, "=");
|
||||
print_string(s, value);
|
||||
print_literal(s, @value);
|
||||
}
|
||||
case (ast::meta_list(?name, ?items)) {
|
||||
word(s.s, name);
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue