about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-07-08 12:55:38 -0700
committerBrian Anderson <banderson@mozilla.com>2011-07-08 14:07:41 -0700
commit4319e7a6556b26cb1db6e933197bef5e97782c2e (patch)
tree61f8bafb0b022a7f4ca4e2b91de94d3903012b11 /src/comp
parent412e203b3c82f654af07fb85cea0c3d4ae89c62e (diff)
downloadrust-4319e7a6556b26cb1db6e933197bef5e97782c2e.tar.gz
rust-4319e7a6556b26cb1db6e933197bef5e97782c2e.zip
Recursively load dependencies of external crates. Issue #632
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/metadata/creader.rs40
-rw-r--r--src/comp/metadata/decoder.rs2
2 files changed, 37 insertions, 5 deletions
diff --git a/src/comp/metadata/creader.rs b/src/comp/metadata/creader.rs
index 5c54074fae1..2b498a5213f 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 f12c7173131..415d5c8d144 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] {