Skip to content

Commit 4319e7a

Browse files
committed
Recursively load dependencies of external crates. Issue #632
1 parent 412e203 commit 4319e7a

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

src/comp/metadata/creader.rs

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,23 +244,53 @@ fn resolve_crate(env e, ast::ident ident, (@ast::meta_item)[] metas,
244244
auto cfilename = cinfo._0;
245245
auto cdata = cinfo._1;
246246

247-
auto cmeta = rec(name=ident,
248-
data=cdata,
249-
cnum_map = new_int_hash[ast::crate_num]());
250-
247+
// Claim this crate number and cache it
251248
auto cnum = e.next_crate_num;
252249
e.crate_cache.insert(ident, cnum);
253250
e.next_crate_num += 1;
254251

252+
// Now resolve the crates referenced by this crate
253+
auto cnum_map = resolve_crate_deps(e, cdata);
254+
255+
auto cmeta = rec(name=ident,
256+
data=cdata,
257+
cnum_map=cnum_map);
258+
255259
auto cstore = e.sess.get_cstore();
256260
cstore::set_crate_data(cstore, cnum, cmeta);
257261
cstore::add_used_crate_file(cstore, cfilename);
258262
ret cnum;
259263
} else {
260264
ret e.crate_cache.get(ident);
261265
}
262-
}
266+
}
263267

268+
// Go through the crate metadata and load any crates that it references
269+
fn resolve_crate_deps(env e, &vec[u8] cdata) -> cstore::cnum_map {
270+
log "resolving deps of external crate";
271+
// The map from crate numbers in the crate we're resolving to local crate
272+
// numbers
273+
auto cnum_map = new_int_hash[ast::crate_num]();
274+
for (decoder::crate_dep dep in decoder::get_crate_deps(cdata)) {
275+
auto extrn_cnum = dep._0;
276+
auto cname = dep._1;
277+
log #fmt("resolving dep %s", cname);
278+
if (e.crate_cache.contains_key(cname)) {
279+
log "already have it";
280+
// We've already seen this crate
281+
auto local_cnum = e.crate_cache.get(cname);
282+
cnum_map.insert(extrn_cnum, local_cnum);
283+
} else {
284+
log "need to load it";
285+
// This is a new one so we've got to load it
286+
// FIXME: Need better error reporting than just a bogus span
287+
auto fake_span = rec(lo=0u,hi=0u);
288+
auto local_cnum = resolve_crate(e, cname, ~[], fake_span);
289+
cnum_map.insert(extrn_cnum, local_cnum);
290+
}
291+
}
292+
ret cnum_map;
293+
}
264294

265295
// Local Variables:
266296
// mode: rust

src/comp/metadata/decoder.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export get_type_param_count;
2424
export lookup_defs;
2525
export get_crate_attributes;
2626
export list_crate_metadata;
27+
export crate_dep;
28+
export get_crate_deps;
2729

2830
fn lookup_hash(&ebml::doc d, fn(vec[u8]) -> bool eq_fn, uint hash) ->
2931
vec[ebml::doc] {

0 commit comments

Comments
 (0)