Skip to content

Commit 3070439

Browse files
committed
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.
1 parent 7c66894 commit 3070439

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

src/comp/metadata/common.rs

+6
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ const uint tag_meta_item_word = 0x23u;
5656

5757
const uint tag_meta_item_list = 0x24u;
5858

59+
// The list of crates that this crate depends on
60+
const uint tag_crate_deps = 0x25u;
61+
62+
// A single crate dependency
63+
const uint tag_crate_dep = 0x26u;
64+
5965
// djb's cdb hashes.
6066
fn hash_node_id(&int node_id) -> uint { ret 177573u ^ (node_id as uint); }
6167

src/comp/metadata/decoder.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ fn list_meta_items(&ebml::doc meta_items, io::writer out) {
327327
}
328328

329329
fn list_crate_attributes(&ebml::doc md, io::writer out) {
330-
out.write_str("=Crate=");
330+
out.write_str("=Crate Attributes=");
331331

332332
for (ast::attribute attr in get_attributes(md)) {
333333
out.write_str(#fmt("%s", pprust::attribute_to_str(attr)));
@@ -340,6 +340,32 @@ fn get_crate_attributes(&vec[u8] data) -> ast::attribute[] {
340340
ret get_attributes(ebml::new_doc(data));
341341
}
342342

343+
type crate_dep = tup(ast::crate_num, str);
344+
345+
fn get_crate_deps(&vec[u8] data) -> vec[crate_dep] {
346+
let vec[crate_dep] deps = [];
347+
auto cratedoc = ebml::new_doc(data);
348+
auto depsdoc = ebml::get_doc(cratedoc, tag_crate_deps);
349+
auto crate_num = 1;
350+
for each (ebml::doc depdoc in
351+
ebml::tagged_docs(depsdoc, tag_crate_dep)) {
352+
auto depname = str::unsafe_from_bytes(ebml::doc_data(depdoc));
353+
deps += [tup(crate_num, depname)];
354+
crate_num += 1;
355+
}
356+
ret deps;
357+
}
358+
359+
fn list_crate_deps(&vec[u8] data, io::writer out) {
360+
out.write_str("=External Dependencies=\n");
361+
362+
for (crate_dep dep in get_crate_deps(data)) {
363+
out.write_str(#fmt("%d %s\n", dep._0, dep._1));
364+
}
365+
366+
out.write_str("\n");
367+
}
368+
343369
fn list_crate_items(vec[u8] bytes, &ebml::doc md, io::writer out) {
344370
out.write_str("=Items=\n");
345371
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) {
364390
fn list_crate_metadata(vec[u8] bytes, io::writer out) {
365391
auto md = ebml::new_doc(bytes);
366392
list_crate_attributes(md, out);
393+
list_crate_deps(bytes, out);
367394
list_crate_items(bytes, md, out);
368395
}
369396

src/comp/metadata/encoder.rs

+46
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,49 @@ fn synthesize_crate_attrs(&@encode_ctxt ecx,
520520
ret attrs;
521521
}
522522

523+
fn encode_crate_deps(&ebml::writer ebml_w, &cstore::cstore cstore) {
524+
525+
fn get_ordered_names(&cstore::cstore cstore) -> vec[str] {
526+
type hashkv = @tup(crate_num, cstore::crate_metadata);
527+
type numname = tup(crate_num, str);
528+
529+
// Pull the cnums and names out of cstore
530+
let vec[mutable numname] pairs = [mutable];
531+
for each (hashkv hashkv in cstore.metas.items()) {
532+
pairs += [mutable tup(hashkv._0, hashkv._1.name)];
533+
}
534+
535+
// Sort by cnum
536+
fn lteq(&numname kv1, &numname kv2) -> bool { kv1._0 <= kv2._0 }
537+
std::sort::quick_sort(lteq, pairs);
538+
539+
// Sanity-check the crate numbers
540+
auto expected_cnum = 1;
541+
for (numname n in pairs) {
542+
assert n._0 == expected_cnum;
543+
expected_cnum += 1;
544+
}
545+
546+
// Return just the names
547+
fn name(&numname kv) -> str { kv._1 }
548+
// mutable -> immutable hack for vec::map
549+
auto immpairs = vec::slice(pairs, 0u, vec::len(pairs));
550+
ret vec::map(name, immpairs);
551+
}
552+
553+
// We're just going to write a list of crate names, with the assumption
554+
// that they are numbered 1 to n.
555+
// FIXME: This is not nearly enough to support correct versioning
556+
// but is enough to get transitive crate dependencies working.
557+
ebml::start_tag(ebml_w, tag_crate_deps);
558+
for (str cname in get_ordered_names(cstore)) {
559+
ebml::start_tag(ebml_w, tag_crate_dep);
560+
ebml_w.writer.write(str::bytes(cname));
561+
ebml::end_tag(ebml_w);
562+
}
563+
ebml::end_tag(ebml_w);
564+
}
565+
523566
fn encode_metadata(&@crate_ctxt cx, &@crate crate) -> str {
524567

525568
auto abbrevs = map::mk_hashmap(ty::hash_ty, ty::eq_ty);
@@ -531,6 +574,9 @@ fn encode_metadata(&@crate_ctxt cx, &@crate crate) -> str {
531574

532575
auto crate_attrs = synthesize_crate_attrs(ecx, crate);
533576
encode_attributes(ebml_w, crate_attrs);
577+
578+
encode_crate_deps(ebml_w, cx.sess.get_cstore());
579+
534580
// Encode and index the paths.
535581

536582
ebml::start_tag(ebml_w, tag_paths);

0 commit comments

Comments
 (0)