parent
a303fd98c7
commit
635e8200e1
4 changed files with 64 additions and 33 deletions
|
@ -1,6 +1,7 @@
|
|||
// Searching for information from the cstore
|
||||
|
||||
import syntax::ast;
|
||||
import syntax::ast_util;
|
||||
import middle::ty;
|
||||
import option::{some, none};
|
||||
import driver::session;
|
||||
|
@ -12,7 +13,6 @@ export get_tag_variants;
|
|||
export get_impls_for_mod;
|
||||
export get_iface_methods;
|
||||
export get_type;
|
||||
export get_item_name;
|
||||
export get_impl_iface;
|
||||
|
||||
fn get_symbol(cstore: cstore::cstore, def: ast::def_id) -> str {
|
||||
|
@ -81,11 +81,6 @@ fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_bounds_and_ty {
|
|||
decoder::get_type(cdata, def.node, tcx)
|
||||
}
|
||||
|
||||
fn get_item_name(cstore: cstore::cstore, cnum: int, id: int) -> ast::ident {
|
||||
let cdata = cstore::get_crate_data(cstore, cnum).data;
|
||||
ret decoder::lookup_item_name(cdata, id);
|
||||
}
|
||||
|
||||
fn get_impl_iface(tcx: ty::ctxt, def: ast::def_id)
|
||||
-> option::t<ty::t> {
|
||||
let cstore = tcx.sess.cstore;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import core::{vec, str};
|
||||
import std::map;
|
||||
import syntax::ast;
|
||||
import util::common::*;
|
||||
|
||||
export cstore;
|
||||
export cnum_map;
|
||||
|
@ -22,6 +23,7 @@ export get_used_link_args;
|
|||
export add_use_stmt_cnum;
|
||||
export get_use_stmt_cnum;
|
||||
export get_dep_hashes;
|
||||
export get_path;
|
||||
|
||||
|
||||
// A map from external crate numbers (as decoded from some crate file) to
|
||||
|
@ -30,6 +32,11 @@ export get_dep_hashes;
|
|||
// own crate numbers.
|
||||
type cnum_map = map::hashmap<ast::crate_num, ast::crate_num>;
|
||||
|
||||
// Multiple items may have the same def_id in crate metadata. They may be
|
||||
// renamed imports or reexports. This map keeps the "real" module path
|
||||
// and def_id.
|
||||
type mod_path_map = map::hashmap<ast::def_id, str>;
|
||||
|
||||
type crate_metadata = @{name: str,
|
||||
data: @[u8],
|
||||
cnum_map: cnum_map,
|
||||
|
@ -45,6 +52,7 @@ enum cstore { private(cstore_private), }
|
|||
type cstore_private =
|
||||
@{metas: map::hashmap<ast::crate_num, crate_metadata>,
|
||||
use_crate_map: use_crate_map,
|
||||
mod_path_map: mod_path_map,
|
||||
mutable used_crate_files: [str],
|
||||
mutable used_libraries: [str],
|
||||
mutable used_link_args: [str]};
|
||||
|
@ -58,8 +66,10 @@ fn p(cstore: cstore) -> cstore_private { alt cstore { private(p) { p } } }
|
|||
fn mk_cstore() -> cstore {
|
||||
let meta_cache = map::new_int_hash::<crate_metadata>();
|
||||
let crate_map = map::new_int_hash::<ast::crate_num>();
|
||||
let mod_path_map = new_def_hash();
|
||||
ret private(@{metas: meta_cache,
|
||||
use_crate_map: crate_map,
|
||||
mod_path_map: mod_path_map,
|
||||
mutable used_crate_files: [],
|
||||
mutable used_libraries: [],
|
||||
mutable used_link_args: []});
|
||||
|
@ -72,6 +82,11 @@ fn get_crate_data(cstore: cstore, cnum: ast::crate_num) -> crate_metadata {
|
|||
fn set_crate_data(cstore: cstore, cnum: ast::crate_num,
|
||||
data: crate_metadata) {
|
||||
p(cstore).metas.insert(cnum, data);
|
||||
vec::iter(decoder::get_crate_module_paths(data.data)) {|dp|
|
||||
let (did, path) = dp;
|
||||
let d = {crate: cnum, node: did.node};
|
||||
p(cstore).mod_path_map.insert(d, path);
|
||||
}
|
||||
}
|
||||
|
||||
fn have_crate_data(cstore: cstore, cnum: ast::crate_num) -> bool {
|
||||
|
@ -144,6 +159,13 @@ fn get_dep_hashes(cstore: cstore) -> [str] {
|
|||
fn mapper(ch: crate_hash) -> str { ret ch.hash; }
|
||||
ret vec::map(sorted, mapper);
|
||||
}
|
||||
|
||||
fn get_path(cstore: cstore, d: ast::def_id) -> [str] {
|
||||
alt p(cstore).mod_path_map.find(d) {
|
||||
option::some(ds) { str::split_str(ds, "::") }
|
||||
option::none { [] }
|
||||
}
|
||||
}
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
// fill-column: 78;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Decoding metadata from a single crate's metadata
|
||||
|
||||
import std::{ebml, io};
|
||||
import std::{ebml, map, io};
|
||||
import io::writer_util;
|
||||
import syntax::{ast, ast_util};
|
||||
import front::attr;
|
||||
|
@ -26,6 +26,8 @@ export get_crate_deps;
|
|||
export get_crate_hash;
|
||||
export get_impls_for_mod;
|
||||
export get_iface_methods;
|
||||
export get_crate_module_paths;
|
||||
|
||||
// A function that takes a def_id relative to the crate being searched and
|
||||
// returns a def_id relative to the compilation environment, i.e. if we hit a
|
||||
// def_id for an item defined in another crate, somebody needs to figure out
|
||||
|
@ -451,8 +453,16 @@ fn get_crate_hash(data: @[u8]) -> str {
|
|||
|
||||
fn list_crate_items(bytes: @[u8], md: ebml::doc, out: io::writer) {
|
||||
out.write_str("=Items=\n");
|
||||
let paths = ebml::get_doc(md, tag_paths);
|
||||
let items = ebml::get_doc(md, tag_items);
|
||||
iter_crate_items(bytes) {|path, did|
|
||||
out.write_str(#fmt["%s (%s)\n", path, describe_def(items, did)]);
|
||||
}
|
||||
out.write_str("\n");
|
||||
}
|
||||
|
||||
fn iter_crate_items(bytes: @[u8], proc: block(str, ast::def_id)) {
|
||||
let md = ebml::new_doc(bytes);
|
||||
let paths = ebml::get_doc(md, tag_paths);
|
||||
let index = ebml::get_doc(paths, tag_index);
|
||||
let bs = ebml::get_doc(index, tag_index_buckets);
|
||||
ebml::tagged_docs(bs, tag_index_buckets_bucket) {|bucket|
|
||||
|
@ -462,11 +472,35 @@ fn list_crate_items(bytes: @[u8], md: ebml::doc, out: io::writer) {
|
|||
let def = ebml::doc_at(bytes, data.pos);
|
||||
let did_doc = ebml::get_doc(def, tag_def_id);
|
||||
let did = parse_def_id(ebml::doc_data(did_doc));
|
||||
out.write_str(#fmt["%s (%s)\n", data.path,
|
||||
describe_def(items, did)]);
|
||||
proc(data.path, did);
|
||||
};
|
||||
};
|
||||
out.write_str("\n");
|
||||
}
|
||||
|
||||
fn get_crate_module_paths(bytes: @[u8]) -> [(ast::def_id, str)] {
|
||||
fn mod_of_path(p: str) -> str {
|
||||
str::connect(vec::init(str::split_str(p, "::")), "::")
|
||||
}
|
||||
|
||||
// find all module (path, def_ids), which are not
|
||||
// fowarded path due to renamed import or reexport
|
||||
let res = [];
|
||||
let mods = map::new_str_hash();
|
||||
iter_crate_items(bytes) {|path, did|
|
||||
let m = mod_of_path(path);
|
||||
if str::is_not_empty(m) {
|
||||
// if m has a sub-item, it must be a module
|
||||
mods.insert(m, true);
|
||||
}
|
||||
// Collect everything by now. There might be multiple
|
||||
// paths pointing to the same did. Those will be
|
||||
// unified later by using the mods map
|
||||
res += [(did, path)];
|
||||
}
|
||||
ret vec::filter(res) {|x|
|
||||
let (_, xp) = x;
|
||||
mods.contains_key(xp)
|
||||
}
|
||||
}
|
||||
|
||||
fn list_crate_metadata(bytes: @[u8], out: io::writer) {
|
||||
|
|
|
@ -1187,7 +1187,7 @@ fn lookup_in_mod(e: env, m: def, sp: span, name: ident, ns: namespace,
|
|||
if !is_none(cached) { ret cached; }
|
||||
let path = [name];
|
||||
if defid.node != ast::crate_node_id {
|
||||
path = e.ext_map.get(defid) + path;
|
||||
path = cstore::get_path(e.cstore, defid) + path;
|
||||
}
|
||||
let fnd = lookup_external(e, defid.crate, path, ns);
|
||||
if !is_none(fnd) {
|
||||
|
@ -1484,27 +1484,7 @@ fn ns_ok(wanted:namespace, actual:namespace) -> bool {
|
|||
fn lookup_external(e: env, cnum: int, ids: [ident], ns: namespace) ->
|
||||
option::t<def> {
|
||||
for d: def in csearch::lookup_defs(e.sess.cstore, cnum, ids) {
|
||||
let did = def_id_of_def(d);
|
||||
alt d {
|
||||
def_mod(_) | def_native_mod(_) {
|
||||
// The [native] module name might have renamed when importing,
|
||||
// find the original name for further lookup of names inside the
|
||||
// [native] module
|
||||
if did.crate != ast::local_crate {
|
||||
let cname = cstore::get_crate_data(e.cstore, did.crate).name;
|
||||
let name =
|
||||
csearch::get_item_name(e.cstore, did.crate, did.node);
|
||||
#debug("lookup_external: %s %d, %d, %s, %s", cname,
|
||||
did.crate, did.node, str::connect(ids, "::"), name);
|
||||
e.ext_map.insert(did, vec::init(ids) + [name]);
|
||||
} else {
|
||||
e.ext_map.insert(did, ids);
|
||||
}
|
||||
}
|
||||
_ {
|
||||
e.ext_map.insert(did, ids);
|
||||
}
|
||||
}
|
||||
e.ext_map.insert(def_id_of_def(d), ids);
|
||||
if ns_ok(ns, ns_for_def(d)) { ret some(d); }
|
||||
}
|
||||
ret none::<def>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue