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:
Brian Anderson 2011-07-08 11:29:56 -07:00
parent 7c66894a71
commit 3070439c00
3 changed files with 80 additions and 1 deletions

View file

@ -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); }

View file

@ -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);
}

View file

@ -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);