From 4319e7a6556b26cb1db6e933197bef5e97782c2e Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 8 Jul 2011 12:55:38 -0700 Subject: [PATCH] Recursively load dependencies of external crates. Issue #632 --- src/comp/metadata/creader.rs | 40 +++++++++++++++++++++++++++++++----- src/comp/metadata/decoder.rs | 2 ++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/comp/metadata/creader.rs b/src/comp/metadata/creader.rs index 5c54074fae19..2b498a5213f7 100644 --- a/src/comp/metadata/creader.rs +++ b/src/comp/metadata/creader.rs @@ -244,14 +244,18 @@ fn resolve_crate(env e, ast::ident ident, (@ast::meta_item)[] metas, auto cfilename = cinfo._0; auto cdata = cinfo._1; - auto cmeta = rec(name=ident, - data=cdata, - cnum_map = new_int_hash[ast::crate_num]()); - + // Claim this crate number and cache it auto cnum = e.next_crate_num; e.crate_cache.insert(ident, cnum); e.next_crate_num += 1; + // Now resolve the crates referenced by this crate + auto cnum_map = resolve_crate_deps(e, cdata); + + auto cmeta = rec(name=ident, + data=cdata, + cnum_map=cnum_map); + auto cstore = e.sess.get_cstore(); cstore::set_crate_data(cstore, cnum, cmeta); cstore::add_used_crate_file(cstore, cfilename); @@ -259,8 +263,34 @@ fn resolve_crate(env e, ast::ident ident, (@ast::meta_item)[] metas, } else { ret e.crate_cache.get(ident); } - } +} +// Go through the crate metadata and load any crates that it references +fn resolve_crate_deps(env e, &vec[u8] cdata) -> cstore::cnum_map { + log "resolving deps of external crate"; + // The map from crate numbers in the crate we're resolving to local crate + // numbers + auto cnum_map = new_int_hash[ast::crate_num](); + for (decoder::crate_dep dep in decoder::get_crate_deps(cdata)) { + auto extrn_cnum = dep._0; + auto cname = dep._1; + log #fmt("resolving dep %s", cname); + if (e.crate_cache.contains_key(cname)) { + log "already have it"; + // We've already seen this crate + auto local_cnum = e.crate_cache.get(cname); + cnum_map.insert(extrn_cnum, local_cnum); + } else { + log "need to load it"; + // This is a new one so we've got to load it + // FIXME: Need better error reporting than just a bogus span + auto fake_span = rec(lo=0u,hi=0u); + auto local_cnum = resolve_crate(e, cname, ~[], fake_span); + cnum_map.insert(extrn_cnum, local_cnum); + } + } + ret cnum_map; +} // Local Variables: // mode: rust diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index f12c71731316..415d5c8d144c 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -24,6 +24,8 @@ export get_type_param_count; export lookup_defs; export get_crate_attributes; export list_crate_metadata; +export crate_dep; +export get_crate_deps; fn lookup_hash(&ebml::doc d, fn(vec[u8]) -> bool eq_fn, uint hash) -> vec[ebml::doc] {