2011-06-28 17:25:20 -05:00
|
|
|
// Functions dealing with attributes and meta_items
|
|
|
|
|
2011-12-13 18:25:51 -06:00
|
|
|
import std::map;
|
2012-03-07 18:48:57 -06:00
|
|
|
import std::map::hashmap;
|
2012-03-16 17:14:37 -05:00
|
|
|
import either::either;
|
2012-03-22 20:01:08 -05:00
|
|
|
import diagnostic::span_handler;
|
2012-06-30 05:54:54 -05:00
|
|
|
import ast_util::{spanned, dummy_spanned};
|
|
|
|
import parse::comments::{doc_comment_style, strip_doc_comment_decoration};
|
2011-06-28 13:24:24 -05:00
|
|
|
|
2012-04-15 03:07:47 -05:00
|
|
|
// Constructors
|
|
|
|
export mk_name_value_item_str;
|
|
|
|
export mk_name_value_item;
|
|
|
|
export mk_list_item;
|
|
|
|
export mk_word_item;
|
|
|
|
export mk_attr;
|
2012-06-30 05:54:54 -05:00
|
|
|
export mk_sugared_doc_attr;
|
2012-04-15 03:07:47 -05:00
|
|
|
|
|
|
|
// Conversion
|
2011-07-05 19:01:23 -05:00
|
|
|
export attr_meta;
|
2011-06-28 14:53:59 -05:00
|
|
|
export attr_metas;
|
2012-06-30 05:54:54 -05:00
|
|
|
export desugar_doc_attr;
|
2012-04-15 03:07:47 -05:00
|
|
|
|
|
|
|
// Accessors
|
|
|
|
export get_attr_name;
|
|
|
|
export get_meta_item_name;
|
|
|
|
export get_meta_item_value_str;
|
|
|
|
export get_meta_item_list;
|
|
|
|
export get_name_value_str_pair;
|
|
|
|
|
|
|
|
// Searching
|
2011-06-28 13:24:24 -05:00
|
|
|
export find_attrs_by_name;
|
2011-06-28 18:52:11 -05:00
|
|
|
export find_meta_items_by_name;
|
2011-06-28 14:53:59 -05:00
|
|
|
export contains;
|
2011-07-13 20:13:19 -05:00
|
|
|
export contains_name;
|
2012-04-15 03:07:47 -05:00
|
|
|
export attrs_contains_name;
|
|
|
|
export first_attr_value_str_by_name;
|
|
|
|
export last_meta_item_value_str_by_name;
|
|
|
|
export last_meta_item_list_by_name;
|
|
|
|
|
|
|
|
// Higher-level applications
|
2011-06-28 17:46:09 -05:00
|
|
|
export sort_meta_items;
|
2011-06-29 16:17:23 -05:00
|
|
|
export remove_meta_items_by_name;
|
2012-04-15 03:07:47 -05:00
|
|
|
export find_linkage_attrs;
|
|
|
|
export find_linkage_metas;
|
2012-06-26 18:18:37 -05:00
|
|
|
export foreign_abi;
|
2012-04-15 03:07:47 -05:00
|
|
|
export inline_attr;
|
|
|
|
export find_inline_attr;
|
|
|
|
export require_unique_names;
|
2011-06-28 13:24:24 -05:00
|
|
|
|
2012-04-15 03:07:47 -05:00
|
|
|
/* Constructors */
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
fn mk_name_value_item_str(+name: ast::ident, +value: ~str) ->
|
|
|
|
@ast::meta_item {
|
2012-06-10 02:49:59 -05:00
|
|
|
let value_lit = dummy_spanned(ast::lit_str(@value));
|
2012-04-15 03:07:47 -05:00
|
|
|
ret mk_name_value_item(name, value_lit);
|
2012-04-06 00:10:51 -05:00
|
|
|
}
|
|
|
|
|
2012-06-07 23:53:47 -05:00
|
|
|
fn mk_name_value_item(+name: ast::ident, +value: ast::lit)
|
|
|
|
-> @ast::meta_item {
|
2012-04-15 03:07:47 -05:00
|
|
|
ret @dummy_spanned(ast::meta_name_value(name, value));
|
2011-06-28 13:24:24 -05:00
|
|
|
}
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
fn mk_list_item(+name: ast::ident, +items: ~[@ast::meta_item]) ->
|
2012-04-15 03:07:47 -05:00
|
|
|
@ast::meta_item {
|
|
|
|
ret @dummy_spanned(ast::meta_list(name, items));
|
2012-03-02 15:14:10 -06:00
|
|
|
}
|
|
|
|
|
2012-06-07 22:12:05 -05:00
|
|
|
fn mk_word_item(+name: ast::ident) -> @ast::meta_item {
|
2012-04-15 03:07:47 -05:00
|
|
|
ret @dummy_spanned(ast::meta_word(name));
|
2012-03-02 12:05:30 -06:00
|
|
|
}
|
|
|
|
|
2012-04-15 03:07:47 -05:00
|
|
|
fn mk_attr(item: @ast::meta_item) -> ast::attribute {
|
2012-06-30 05:54:54 -05:00
|
|
|
ret dummy_spanned({style: ast::attr_inner, value: *item,
|
|
|
|
is_sugared_doc: false});
|
2011-06-28 13:24:24 -05:00
|
|
|
}
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
fn mk_sugared_doc_attr(text: ~str, lo: uint, hi: uint) -> ast::attribute {
|
2012-06-30 05:54:54 -05:00
|
|
|
let lit = spanned(lo, hi, ast::lit_str(@text));
|
|
|
|
let attr = {
|
|
|
|
style: doc_comment_style(text),
|
2012-07-14 00:57:48 -05:00
|
|
|
value: spanned(lo, hi, ast::meta_name_value(@~"doc", lit)),
|
2012-06-30 05:54:54 -05:00
|
|
|
is_sugared_doc: true
|
|
|
|
};
|
|
|
|
ret spanned(lo, hi, attr);
|
|
|
|
}
|
2012-04-15 03:07:47 -05:00
|
|
|
|
|
|
|
/* Conversion */
|
|
|
|
|
|
|
|
fn attr_meta(attr: ast::attribute) -> @ast::meta_item { @attr.node.value }
|
|
|
|
|
|
|
|
// Get the meta_items from inside a vector of attributes
|
2012-06-29 18:26:56 -05:00
|
|
|
fn attr_metas(attrs: ~[ast::attribute]) -> ~[@ast::meta_item] {
|
|
|
|
let mut mitems = ~[];
|
2012-06-30 18:19:07 -05:00
|
|
|
for attrs.each |a| { vec::push(mitems, attr_meta(a)); }
|
2012-04-15 03:07:47 -05:00
|
|
|
ret mitems;
|
2012-01-26 18:23:34 -06:00
|
|
|
}
|
|
|
|
|
2012-06-30 05:54:54 -05:00
|
|
|
fn desugar_doc_attr(attr: ast::attribute) -> ast::attribute {
|
|
|
|
if attr.node.is_sugared_doc {
|
|
|
|
let comment = get_meta_item_value_str(@attr.node.value).get();
|
2012-07-14 00:57:48 -05:00
|
|
|
let meta = mk_name_value_item_str(@~"doc",
|
2012-06-30 05:54:54 -05:00
|
|
|
strip_doc_comment_decoration(*comment));
|
|
|
|
ret mk_attr(meta);
|
|
|
|
} else {
|
|
|
|
attr
|
|
|
|
}
|
|
|
|
}
|
2012-04-15 03:07:47 -05:00
|
|
|
|
|
|
|
/* Accessors */
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn get_attr_name(attr: ast::attribute) -> ast::ident {
|
2011-06-28 13:24:24 -05:00
|
|
|
get_meta_item_name(@attr.node.value)
|
|
|
|
}
|
|
|
|
|
2012-06-14 20:46:33 -05:00
|
|
|
// All "bad" FIXME copies are as per #2543
|
2011-09-12 04:27:30 -05:00
|
|
|
fn get_meta_item_name(meta: @ast::meta_item) -> ast::ident {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt meta.node {
|
2012-06-21 18:44:10 -05:00
|
|
|
ast::meta_word(n) { /* FIXME (#2543) */ copy n }
|
|
|
|
ast::meta_name_value(n, _) { /* FIXME (#2543) */ copy n }
|
|
|
|
ast::meta_list(n, _) { /* FIXME (#2543) */ copy n }
|
2011-06-28 13:24:24 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* Gets the string value if the meta_item is a meta_name_value variant
|
|
|
|
* containing a string, otherwise none
|
|
|
|
*/
|
2012-07-14 00:57:48 -05:00
|
|
|
fn get_meta_item_value_str(meta: @ast::meta_item) -> option<@~str> {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt meta.node {
|
|
|
|
ast::meta_name_value(_, v) {
|
2012-06-07 22:12:05 -05:00
|
|
|
alt v.node {
|
|
|
|
ast::lit_str(s) {
|
2012-06-10 02:49:59 -05:00
|
|
|
option::some(s)
|
2012-06-07 22:12:05 -05:00
|
|
|
}
|
|
|
|
_ {
|
|
|
|
option::none
|
|
|
|
}
|
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
_ { option::none }
|
2011-07-05 19:01:23 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Gets a list of inner meta items from a list meta_item type
|
2012-06-29 18:26:56 -05:00
|
|
|
fn get_meta_item_list(meta: @ast::meta_item) -> option<~[@ast::meta_item]> {
|
2011-10-29 19:35:45 -05:00
|
|
|
alt meta.node {
|
2012-06-21 18:44:10 -05:00
|
|
|
ast::meta_list(_, l) { option::some(/* FIXME (#2543) */ copy l) }
|
2011-10-29 19:35:45 -05:00
|
|
|
_ { option::none }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* If the meta item is a nam-value type with a string value then returns
|
|
|
|
* a tuple containing the name and string value, otherwise `none`
|
|
|
|
*/
|
2012-04-15 03:07:47 -05:00
|
|
|
fn get_name_value_str_pair(
|
|
|
|
item: @ast::meta_item
|
2012-07-14 00:57:48 -05:00
|
|
|
) -> option<(ast::ident, @~str)> {
|
2012-04-15 03:07:47 -05:00
|
|
|
alt attr::get_meta_item_value_str(item) {
|
|
|
|
some(value) {
|
|
|
|
let name = attr::get_meta_item_name(item);
|
2012-06-10 02:49:59 -05:00
|
|
|
some((name, value))
|
2012-04-15 03:07:47 -05:00
|
|
|
}
|
|
|
|
none { none }
|
|
|
|
}
|
|
|
|
}
|
2011-06-28 14:53:59 -05:00
|
|
|
|
2012-04-15 03:07:47 -05:00
|
|
|
|
|
|
|
/* Searching */
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Search a list of attributes and return only those with a specific name
|
2012-07-14 00:57:48 -05:00
|
|
|
fn find_attrs_by_name(attrs: ~[ast::attribute], +name: ~str) ->
|
2012-06-29 18:26:56 -05:00
|
|
|
~[ast::attribute] {
|
2012-04-15 03:07:47 -05:00
|
|
|
let filter = (
|
|
|
|
fn@(a: ast::attribute) -> option<ast::attribute> {
|
2012-06-10 02:49:59 -05:00
|
|
|
if *get_attr_name(a) == name {
|
2012-04-15 03:07:47 -05:00
|
|
|
option::some(a)
|
|
|
|
} else { option::none }
|
|
|
|
}
|
|
|
|
);
|
|
|
|
ret vec::filter_map(attrs, filter);
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// Searcha list of meta items and return only those with a specific name
|
2012-07-14 00:57:48 -05:00
|
|
|
fn find_meta_items_by_name(metas: ~[@ast::meta_item], +name: ~str) ->
|
2012-06-29 18:26:56 -05:00
|
|
|
~[@ast::meta_item] {
|
2012-04-15 03:07:47 -05:00
|
|
|
let filter = fn@(&&m: @ast::meta_item) -> option<@ast::meta_item> {
|
2012-06-10 02:49:59 -05:00
|
|
|
if *get_meta_item_name(m) == name {
|
2012-04-15 03:07:47 -05:00
|
|
|
option::some(m)
|
|
|
|
} else { option::none }
|
|
|
|
};
|
|
|
|
ret vec::filter_map(metas, filter);
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* Returns true if a list of meta items contains another meta item. The
|
|
|
|
* comparison is performed structurally.
|
|
|
|
*/
|
2012-06-29 18:26:56 -05:00
|
|
|
fn contains(haystack: ~[@ast::meta_item], needle: @ast::meta_item) -> bool {
|
2012-07-30 18:01:07 -05:00
|
|
|
debug!{"looking for %s",
|
|
|
|
print::pprust::meta_item_to_str(*needle)};
|
2012-06-30 18:19:07 -05:00
|
|
|
for haystack.each |item| {
|
2012-07-30 18:01:07 -05:00
|
|
|
debug!{"looking in %s",
|
|
|
|
print::pprust::meta_item_to_str(*item)};
|
|
|
|
if eq(item, needle) { debug!{"found it!"}; ret true; }
|
2012-04-15 03:07:47 -05:00
|
|
|
}
|
|
|
|
#debug("found it not :(");
|
|
|
|
ret false;
|
2011-06-28 14:53:59 -05:00
|
|
|
}
|
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool {
|
|
|
|
ret alt a.node {
|
|
|
|
ast::meta_word(na) {
|
|
|
|
alt b.node { ast::meta_word(nb) { na == nb } _ { false } }
|
|
|
|
}
|
|
|
|
ast::meta_name_value(na, va) {
|
|
|
|
alt b.node {
|
|
|
|
ast::meta_name_value(nb, vb) { na == nb && va.node == vb.node }
|
|
|
|
_ { false }
|
2011-06-28 14:53:59 -05:00
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
ast::meta_list(na, la) {
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
// ~[Fixme-sorting]
|
2011-07-01 14:51:46 -05:00
|
|
|
// FIXME (#607): Needs implementing
|
|
|
|
// This involves probably sorting the list by name and
|
|
|
|
// meta_item variant
|
2012-07-14 00:57:48 -05:00
|
|
|
fail ~"unimplemented meta_item variant"
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2011-06-28 14:53:59 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
fn contains_name(metas: ~[@ast::meta_item], +name: ~str) -> bool {
|
2011-07-27 07:19:39 -05:00
|
|
|
let matches = find_meta_items_by_name(metas, name);
|
2011-08-15 18:38:23 -05:00
|
|
|
ret vec::len(matches) > 0u;
|
2011-07-13 20:13:19 -05:00
|
|
|
}
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
fn attrs_contains_name(attrs: ~[ast::attribute], +name: ~str) -> bool {
|
2012-04-15 03:07:47 -05:00
|
|
|
vec::is_not_empty(find_attrs_by_name(attrs, name))
|
|
|
|
}
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
fn first_attr_value_str_by_name(attrs: ~[ast::attribute], +name: ~str)
|
|
|
|
-> option<@~str> {
|
2012-04-15 03:07:47 -05:00
|
|
|
let mattrs = find_attrs_by_name(attrs, name);
|
|
|
|
if vec::len(mattrs) > 0u {
|
|
|
|
ret get_meta_item_value_str(attr_meta(mattrs[0]));
|
|
|
|
}
|
|
|
|
ret option::none;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn last_meta_item_by_name(
|
2012-06-29 18:26:56 -05:00
|
|
|
items: ~[@ast::meta_item],
|
2012-07-14 00:57:48 -05:00
|
|
|
+name: ~str
|
2012-04-15 03:07:47 -05:00
|
|
|
) -> option<@ast::meta_item> {
|
|
|
|
let items = attr::find_meta_items_by_name(items, name);
|
|
|
|
vec::last_opt(items)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn last_meta_item_value_str_by_name(
|
2012-06-29 18:26:56 -05:00
|
|
|
items: ~[@ast::meta_item],
|
2012-07-14 00:57:48 -05:00
|
|
|
+name: ~str
|
|
|
|
) -> option<@~str> {
|
2012-04-15 03:07:47 -05:00
|
|
|
alt last_meta_item_by_name(items, name) {
|
|
|
|
some(item) {
|
|
|
|
alt attr::get_meta_item_value_str(item) {
|
2012-06-10 02:49:59 -05:00
|
|
|
some(value) { some(value) }
|
2012-04-15 03:07:47 -05:00
|
|
|
none { none }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
none { none }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn last_meta_item_list_by_name(
|
2012-06-29 18:26:56 -05:00
|
|
|
items: ~[@ast::meta_item],
|
2012-07-14 00:57:48 -05:00
|
|
|
+name: ~str
|
2012-06-29 18:26:56 -05:00
|
|
|
) -> option<~[@ast::meta_item]> {
|
2012-04-15 03:07:47 -05:00
|
|
|
alt last_meta_item_by_name(items, name) {
|
|
|
|
some(item) {
|
|
|
|
attr::get_meta_item_list(item)
|
|
|
|
}
|
|
|
|
none { none }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Higher-level applications */
|
|
|
|
|
2012-06-21 18:44:10 -05:00
|
|
|
// FIXME (#607): This needs to sort by meta_item variant in addition to
|
|
|
|
// the item name (See [Fixme-sorting])
|
2012-06-29 18:26:56 -05:00
|
|
|
fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] {
|
2011-10-06 05:26:12 -05:00
|
|
|
fn lteq(&&ma: @ast::meta_item, &&mb: @ast::meta_item) -> bool {
|
2011-09-12 04:27:30 -05:00
|
|
|
fn key(m: @ast::meta_item) -> ast::ident {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt m.node {
|
2012-06-21 18:44:10 -05:00
|
|
|
ast::meta_word(name) { /* FIXME (#2543) */ copy name }
|
|
|
|
ast::meta_name_value(name, _) { /* FIXME (#2543) */ copy name }
|
|
|
|
ast::meta_list(name, _) { /* FIXME (#2543) */ copy name }
|
2011-06-28 17:46:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ret key(ma) <= key(mb);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is sort of stupid here, converting to a vec of mutables and back
|
2012-06-29 18:26:56 -05:00
|
|
|
let v: ~[mut @ast::meta_item] = vec::to_mut(items);
|
2011-08-12 00:48:08 -05:00
|
|
|
std::sort::quick_sort(lteq, v);
|
2012-06-02 21:03:28 -05:00
|
|
|
ret vec::from_mut(v);
|
2011-06-28 17:46:09 -05:00
|
|
|
}
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ast::ident) ->
|
|
|
|
~[@ast::meta_item] {
|
2011-06-29 16:17:23 -05:00
|
|
|
|
2012-06-30 18:19:07 -05:00
|
|
|
ret vec::filter_map(items, |item| {
|
2012-01-11 11:58:05 -06:00
|
|
|
if get_meta_item_name(item) != name {
|
2012-06-21 18:44:10 -05:00
|
|
|
option::some(/* FIXME (#2543) */ copy item)
|
2012-06-07 22:12:05 -05:00
|
|
|
} else {
|
|
|
|
option::none
|
|
|
|
}
|
|
|
|
});
|
2011-06-29 16:17:23 -05:00
|
|
|
}
|
|
|
|
|
2012-06-29 18:26:56 -05:00
|
|
|
fn find_linkage_attrs(attrs: ~[ast::attribute]) -> ~[ast::attribute] {
|
|
|
|
let mut found = ~[];
|
2012-07-14 00:57:48 -05:00
|
|
|
for find_attrs_by_name(attrs, ~"link").each |attr| {
|
2012-04-15 03:07:47 -05:00
|
|
|
alt attr.node.value.node {
|
2012-06-28 01:09:51 -05:00
|
|
|
ast::meta_list(_, _) { vec::push(found, attr) }
|
2012-07-30 18:01:07 -05:00
|
|
|
_ { debug!{"ignoring link attribute that has incorrect type"}; }
|
2012-04-15 03:07:47 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ret found;
|
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/**
|
|
|
|
* From a list of crate attributes get only the meta_items that impact crate
|
|
|
|
* linkage
|
|
|
|
*/
|
2012-06-29 18:26:56 -05:00
|
|
|
fn find_linkage_metas(attrs: ~[ast::attribute]) -> ~[@ast::meta_item] {
|
2012-06-30 18:19:07 -05:00
|
|
|
do find_linkage_attrs(attrs).flat_map |attr| {
|
2012-04-15 03:07:47 -05:00
|
|
|
alt check attr.node.value.node {
|
2012-06-21 18:44:10 -05:00
|
|
|
ast::meta_list(_, items) { /* FIXME (#2543) */ copy items }
|
2011-07-05 13:46:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
fn foreign_abi(attrs: ~[ast::attribute]) -> either<~str, ast::foreign_abi> {
|
|
|
|
ret alt attr::first_attr_value_str_by_name(attrs, ~"abi") {
|
2012-01-19 00:37:22 -06:00
|
|
|
option::none {
|
2012-06-26 18:18:37 -05:00
|
|
|
either::right(ast::foreign_abi_cdecl)
|
2011-11-20 12:15:40 -06:00
|
|
|
}
|
2012-07-14 00:57:48 -05:00
|
|
|
option::some(@~"rust-intrinsic") {
|
2012-06-26 18:18:37 -05:00
|
|
|
either::right(ast::foreign_abi_rust_intrinsic)
|
2012-03-23 06:51:20 -05:00
|
|
|
}
|
2012-07-14 00:57:48 -05:00
|
|
|
option::some(@~"cdecl") {
|
2012-06-26 18:18:37 -05:00
|
|
|
either::right(ast::foreign_abi_cdecl)
|
2011-11-20 12:15:40 -06:00
|
|
|
}
|
2012-07-14 00:57:48 -05:00
|
|
|
option::some(@~"stdcall") {
|
2012-06-26 18:18:37 -05:00
|
|
|
either::right(ast::foreign_abi_stdcall)
|
2011-11-20 12:15:40 -06:00
|
|
|
}
|
|
|
|
option::some(t) {
|
2012-07-14 00:57:48 -05:00
|
|
|
either::left(~"unsupported abi: " + *t)
|
2011-11-20 12:15:40 -06:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2012-04-15 03:07:47 -05:00
|
|
|
enum inline_attr {
|
|
|
|
ia_none,
|
|
|
|
ia_hint,
|
2012-07-25 19:29:34 -05:00
|
|
|
ia_always,
|
|
|
|
ia_never,
|
2012-01-16 23:12:08 -06:00
|
|
|
}
|
|
|
|
|
2012-07-04 16:53:12 -05:00
|
|
|
/// True if something like #[inline] is found in the list of attrs.
|
2012-06-29 18:26:56 -05:00
|
|
|
fn find_inline_attr(attrs: ~[ast::attribute]) -> inline_attr {
|
2012-07-05 17:58:25 -05:00
|
|
|
// FIXME (#2809)---validate the usage of #[inline] and #[inline(always)]
|
2012-06-30 18:19:07 -05:00
|
|
|
do vec::foldl(ia_none, attrs) |ia,attr| {
|
2012-04-15 03:07:47 -05:00
|
|
|
alt attr.node.value.node {
|
2012-07-14 00:57:48 -05:00
|
|
|
ast::meta_word(@~"inline") { ia_hint }
|
|
|
|
ast::meta_list(@~"inline", items) {
|
|
|
|
if !vec::is_empty(find_meta_items_by_name(items, ~"always")) {
|
2012-04-15 03:07:47 -05:00
|
|
|
ia_always
|
2012-07-25 19:29:34 -05:00
|
|
|
} else if !vec::is_empty(
|
|
|
|
find_meta_items_by_name(items, ~"never")) {
|
|
|
|
ia_never
|
2012-04-15 03:07:47 -05:00
|
|
|
} else {
|
|
|
|
ia_hint
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ { ia }
|
2012-01-16 23:12:08 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-15 03:07:47 -05:00
|
|
|
fn require_unique_names(diagnostic: span_handler,
|
2012-06-29 18:26:56 -05:00
|
|
|
metas: ~[@ast::meta_item]) {
|
2012-04-15 03:07:47 -05:00
|
|
|
let map = map::str_hash();
|
2012-06-30 18:19:07 -05:00
|
|
|
for metas.each |meta| {
|
2012-04-15 03:07:47 -05:00
|
|
|
let name = get_meta_item_name(meta);
|
2012-06-07 22:12:05 -05:00
|
|
|
|
2012-06-14 20:46:33 -05:00
|
|
|
// FIXME: How do I silence the warnings? --pcw (#2619)
|
2012-06-10 02:49:59 -05:00
|
|
|
if map.contains_key(*name) {
|
2012-04-15 03:07:47 -05:00
|
|
|
diagnostic.span_fatal(meta.span,
|
2012-07-30 18:01:07 -05:00
|
|
|
fmt!{"duplicate meta item `%s`", *name});
|
2012-04-15 03:07:47 -05:00
|
|
|
}
|
2012-06-10 02:49:59 -05:00
|
|
|
map.insert(*name, ());
|
2012-01-16 23:12:08 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-28 13:24:24 -05:00
|
|
|
//
|
|
|
|
// Local Variables:
|
|
|
|
// mode: rust
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
|
|
|
// End:
|
|
|
|
//
|