Skip to content

Commit b0e6c48

Browse files
committed
---
yaml --- r: 3464 b: refs/heads/master c: 29afe1a h: refs/heads/master v: v3
1 parent e92acc7 commit b0e6c48

File tree

3 files changed

+84
-2
lines changed

3 files changed

+84
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 308bc31f242d2c1e0e41f5d13a980315b5ce1afb
2+
refs/heads/master: 29afe1a518dac8bcaae3f2e9e9b246193fb6868d

trunk/src/comp/metadata/encoder.rs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import tags::*;
1313
import middle::trans::crate_ctxt;
1414
import middle::trans::node_id_type;
1515
import middle::ty;
16+
import middle::attr;
1617

1718
export def_to_str;
1819
export hash_path;
@@ -457,12 +458,76 @@ fn encode_attributes(&ebml::writer ebml_w, &vec[attribute] attrs) {
457458
ebml::end_tag(ebml_w);
458459
}
459460

461+
// So there's a special crate attribute called 'link' which defines the metadata
462+
// that Rust cares about for linking crates. This attribute requires name and
463+
// value attributes, so if the user didn't provide them we will throw them in
464+
// anyway with default values.
465+
fn synthesize_crate_attrs(&@crate_ctxt cx,
466+
&@crate crate) -> vec[attribute] {
467+
468+
fn synthesize_link_attr(&@crate_ctxt cx,
469+
&vec[@meta_item] items)
470+
-> attribute {
471+
472+
auto bogus_span = rec(lo = 0u, hi = 0u);
473+
474+
auto name_item_ = meta_name_value("name", cx.link_meta.name);
475+
auto name_item = rec(node=name_item_,
476+
span=bogus_span);
477+
478+
auto vers_item_ = meta_name_value("vers", cx.link_meta.vers);
479+
auto vers_item = rec(node=vers_item_,
480+
span=bogus_span);
481+
482+
auto other_items = {
483+
auto tmp = attr::remove_meta_items_by_name(items, "name");
484+
attr::remove_meta_items_by_name(tmp, "vers")
485+
};
486+
487+
auto meta_items = [@name_item] + [@vers_item] + other_items;
488+
489+
auto link_item_ = meta_list("link", meta_items);
490+
auto link_item = rec(node=link_item_,
491+
span=bogus_span);
492+
493+
auto attr_ = rec(style = attr_inner,
494+
value = link_item);
495+
auto attr = rec(node=attr_,
496+
span=bogus_span);
497+
498+
ret attr;
499+
}
500+
501+
let vec[attribute] attrs = [];
502+
auto found_link_attr = false;
503+
for (attribute attr in crate.node.attrs) {
504+
attrs += if (attr::get_attr_name(attr) != "link") {
505+
[attr]
506+
} else {
507+
alt (attr.node.value.node) {
508+
case (meta_list(?n, ?l)) {
509+
found_link_attr = true;
510+
[synthesize_link_attr(cx, l)]
511+
}
512+
case (_) { [attr] }
513+
}
514+
}
515+
}
516+
517+
if (!found_link_attr) {
518+
attrs += [synthesize_link_attr(cx, [])];
519+
}
520+
521+
ret attrs;
522+
}
523+
460524
fn encode_metadata(&@crate_ctxt cx, &@crate crate) -> str {
461525
auto string_w = io::string_writer();
462526
auto buf_w = string_w.get_writer().get_buf_writer();
463527
auto ebml_w = ebml::create_writer(buf_w);
464528

465-
encode_attributes(ebml_w, crate.node.attrs);
529+
auto crate_attrs = synthesize_crate_attrs(cx, crate);
530+
encode_attributes(ebml_w, crate_attrs);
466531
// Encode and index the paths.
467532

468533
ebml::start_tag(ebml_w, tag_paths);

trunk/src/comp/middle/attr.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ export find_attrs_by_name;
1010
export find_meta_items_by_name;
1111
export contains;
1212
export sort_meta_items;
13+
export remove_meta_items_by_name;
14+
export get_attr_name;
1315

1416
// From a list of crate attributes get only the meta_items that impact crate
1517
// linkage
@@ -138,6 +140,21 @@ fn sort_meta_items(&vec[@ast::meta_item] items) -> vec[@ast::meta_item] {
138140
ret v2;
139141
}
140142

143+
fn remove_meta_items_by_name(&vec[@ast::meta_item] items,
144+
str name) -> vec[@ast::meta_item] {
145+
146+
auto filter = bind fn(&@ast::meta_item item,
147+
str name) -> option::t[@ast::meta_item] {
148+
if (get_meta_item_name(item) != name) {
149+
option::some(item)
150+
} else {
151+
option::none
152+
}
153+
} (_, name);
154+
155+
ret vec::filter_map(filter, items);
156+
}
157+
141158
//
142159
// Local Variables:
143160
// mode: rust

0 commit comments

Comments
 (0)