diff --git a/src/comp/metadata/common.rs b/src/comp/metadata/common.rs index 5393e1d0b7ed..58db989cba30 100644 --- a/src/comp/metadata/common.rs +++ b/src/comp/metadata/common.rs @@ -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); } diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index 30d016b2cf17..8aab0e739fcf 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -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); } diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index 53af9b00dbc1..89634d233bff 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -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);