Encode/decode a crate's externel dependencies. Issue #632
The encoding is very simple right now, just the crate name. Ultimately this won't be enough for our versioning needs, but it should fill our immediate need of being able to correlate encoded crate numbers to actual crates.
This commit is contained in:
parent
7c66894a71
commit
3070439c00
3 changed files with 80 additions and 1 deletions
|
|
@ -56,6 +56,12 @@ const uint tag_meta_item_word = 0x23u;
|
|||
|
||||
const uint tag_meta_item_list = 0x24u;
|
||||
|
||||
// The list of crates that this crate depends on
|
||||
const uint tag_crate_deps = 0x25u;
|
||||
|
||||
// A single crate dependency
|
||||
const uint tag_crate_dep = 0x26u;
|
||||
|
||||
// djb's cdb hashes.
|
||||
fn hash_node_id(&int node_id) -> uint { ret 177573u ^ (node_id as uint); }
|
||||
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ fn list_meta_items(&ebml::doc meta_items, io::writer out) {
|
|||
}
|
||||
|
||||
fn list_crate_attributes(&ebml::doc md, io::writer out) {
|
||||
out.write_str("=Crate=");
|
||||
out.write_str("=Crate Attributes=");
|
||||
|
||||
for (ast::attribute attr in get_attributes(md)) {
|
||||
out.write_str(#fmt("%s", pprust::attribute_to_str(attr)));
|
||||
|
|
@ -340,6 +340,32 @@ fn get_crate_attributes(&vec[u8] data) -> ast::attribute[] {
|
|||
ret get_attributes(ebml::new_doc(data));
|
||||
}
|
||||
|
||||
type crate_dep = tup(ast::crate_num, str);
|
||||
|
||||
fn get_crate_deps(&vec[u8] data) -> vec[crate_dep] {
|
||||
let vec[crate_dep] deps = [];
|
||||
auto cratedoc = ebml::new_doc(data);
|
||||
auto depsdoc = ebml::get_doc(cratedoc, tag_crate_deps);
|
||||
auto crate_num = 1;
|
||||
for each (ebml::doc depdoc in
|
||||
ebml::tagged_docs(depsdoc, tag_crate_dep)) {
|
||||
auto depname = str::unsafe_from_bytes(ebml::doc_data(depdoc));
|
||||
deps += [tup(crate_num, depname)];
|
||||
crate_num += 1;
|
||||
}
|
||||
ret deps;
|
||||
}
|
||||
|
||||
fn list_crate_deps(&vec[u8] data, io::writer out) {
|
||||
out.write_str("=External Dependencies=\n");
|
||||
|
||||
for (crate_dep dep in get_crate_deps(data)) {
|
||||
out.write_str(#fmt("%d %s\n", dep._0, dep._1));
|
||||
}
|
||||
|
||||
out.write_str("\n");
|
||||
}
|
||||
|
||||
fn list_crate_items(vec[u8] bytes, &ebml::doc md, io::writer out) {
|
||||
out.write_str("=Items=\n");
|
||||
auto paths = ebml::get_doc(md, tag_paths);
|
||||
|
|
@ -364,6 +390,7 @@ fn list_crate_items(vec[u8] bytes, &ebml::doc md, io::writer out) {
|
|||
fn list_crate_metadata(vec[u8] bytes, io::writer out) {
|
||||
auto md = ebml::new_doc(bytes);
|
||||
list_crate_attributes(md, out);
|
||||
list_crate_deps(bytes, out);
|
||||
list_crate_items(bytes, md, out);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -520,6 +520,49 @@ fn synthesize_crate_attrs(&@encode_ctxt ecx,
|
|||
ret attrs;
|
||||
}
|
||||
|
||||
fn encode_crate_deps(&ebml::writer ebml_w, &cstore::cstore cstore) {
|
||||
|
||||
fn get_ordered_names(&cstore::cstore cstore) -> vec[str] {
|
||||
type hashkv = @tup(crate_num, cstore::crate_metadata);
|
||||
type numname = tup(crate_num, str);
|
||||
|
||||
// Pull the cnums and names out of cstore
|
||||
let vec[mutable numname] pairs = [mutable];
|
||||
for each (hashkv hashkv in cstore.metas.items()) {
|
||||
pairs += [mutable tup(hashkv._0, hashkv._1.name)];
|
||||
}
|
||||
|
||||
// Sort by cnum
|
||||
fn lteq(&numname kv1, &numname kv2) -> bool { kv1._0 <= kv2._0 }
|
||||
std::sort::quick_sort(lteq, pairs);
|
||||
|
||||
// Sanity-check the crate numbers
|
||||
auto expected_cnum = 1;
|
||||
for (numname n in pairs) {
|
||||
assert n._0 == expected_cnum;
|
||||
expected_cnum += 1;
|
||||
}
|
||||
|
||||
// Return just the names
|
||||
fn name(&numname kv) -> str { kv._1 }
|
||||
// mutable -> immutable hack for vec::map
|
||||
auto immpairs = vec::slice(pairs, 0u, vec::len(pairs));
|
||||
ret vec::map(name, immpairs);
|
||||
}
|
||||
|
||||
// We're just going to write a list of crate names, with the assumption
|
||||
// that they are numbered 1 to n.
|
||||
// FIXME: This is not nearly enough to support correct versioning
|
||||
// but is enough to get transitive crate dependencies working.
|
||||
ebml::start_tag(ebml_w, tag_crate_deps);
|
||||
for (str cname in get_ordered_names(cstore)) {
|
||||
ebml::start_tag(ebml_w, tag_crate_dep);
|
||||
ebml_w.writer.write(str::bytes(cname));
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
|
||||
fn encode_metadata(&@crate_ctxt cx, &@crate crate) -> str {
|
||||
|
||||
auto abbrevs = map::mk_hashmap(ty::hash_ty, ty::eq_ty);
|
||||
|
|
@ -531,6 +574,9 @@ fn encode_metadata(&@crate_ctxt cx, &@crate crate) -> str {
|
|||
|
||||
auto crate_attrs = synthesize_crate_attrs(ecx, crate);
|
||||
encode_attributes(ebml_w, crate_attrs);
|
||||
|
||||
encode_crate_deps(ebml_w, cx.sess.get_cstore());
|
||||
|
||||
// Encode and index the paths.
|
||||
|
||||
ebml::start_tag(ebml_w, tag_paths);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue