Track all exports in exp_map
This is needed because the reachability checker needs to be able to follow exports. Issue #1934
This commit is contained in:
parent
19508c7d53
commit
4e4bd585cd
|
@ -159,12 +159,17 @@ fn encode_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt, crate: @crate)
|
||||||
|
|
||||||
fn encode_reexport_paths(ebml_w: ebml::writer,
|
fn encode_reexport_paths(ebml_w: ebml::writer,
|
||||||
ecx: @encode_ctxt, &index: [entry<str>]) {
|
ecx: @encode_ctxt, &index: [entry<str>]) {
|
||||||
ecx.ccx.exp_map.items {|path, defs|
|
let tcx = ecx.ccx.tcx;
|
||||||
for def in *defs {
|
ecx.ccx.exp_map.items {|exp_id, defs|
|
||||||
|
for def in defs {
|
||||||
|
if !def.reexp { cont; }
|
||||||
|
let path = alt check tcx.items.get(exp_id) {
|
||||||
|
ast_map::node_export(_, path) { ast_map::path_to_str(*path) }
|
||||||
|
};
|
||||||
index += [{val: path, pos: ebml_w.writer.tell()}];
|
index += [{val: path, pos: ebml_w.writer.tell()}];
|
||||||
ebml_w.start_tag(tag_paths_data_item);
|
ebml_w.start_tag(tag_paths_data_item);
|
||||||
encode_name(ebml_w, path);
|
encode_name(ebml_w, path);
|
||||||
encode_def_id(ebml_w, ast_util::def_id_of_def(def));
|
encode_def_id(ebml_w, def.id);
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ enum ast_node {
|
||||||
node_method(@method, def_id /* impl did */, @path /* path to the impl */),
|
node_method(@method, def_id /* impl did */, @path /* path to the impl */),
|
||||||
node_variant(variant, def_id, @path),
|
node_variant(variant, def_id, @path),
|
||||||
node_expr(@expr),
|
node_expr(@expr),
|
||||||
|
node_export(@view_path, @path),
|
||||||
// Locals are numbered, because the alias analysis needs to know in which
|
// Locals are numbered, because the alias analysis needs to know in which
|
||||||
// order they are introduced.
|
// order they are introduced.
|
||||||
node_arg(arg, uint),
|
node_arg(arg, uint),
|
||||||
|
@ -38,6 +39,10 @@ type map = std::map::map<node_id, ast_node>;
|
||||||
type ctx = {map: map, mutable path: path, mutable local_id: uint};
|
type ctx = {map: map, mutable path: path, mutable local_id: uint};
|
||||||
type vt = visit::vt<ctx>;
|
type vt = visit::vt<ctx>;
|
||||||
|
|
||||||
|
fn extend(cx: ctx, elt: str) -> @path {
|
||||||
|
@(cx.path + [path_name(elt)])
|
||||||
|
}
|
||||||
|
|
||||||
fn mk_ast_map_visitor() -> vt {
|
fn mk_ast_map_visitor() -> vt {
|
||||||
ret visit::mk_vt(@{
|
ret visit::mk_vt(@{
|
||||||
visit_item: map_item,
|
visit_item: map_item,
|
||||||
|
@ -45,7 +50,8 @@ fn mk_ast_map_visitor() -> vt {
|
||||||
visit_expr: map_expr,
|
visit_expr: map_expr,
|
||||||
visit_fn: map_fn,
|
visit_fn: map_fn,
|
||||||
visit_local: map_local,
|
visit_local: map_local,
|
||||||
visit_arm: map_arm
|
visit_arm: map_arm,
|
||||||
|
visit_view_item: map_view_item
|
||||||
with *visit::default_visitor()
|
with *visit::default_visitor()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -140,20 +146,38 @@ fn map_item(i: @item, cx: ctx, v: vt) {
|
||||||
item_enum(vs, _) {
|
item_enum(vs, _) {
|
||||||
for v in vs {
|
for v in vs {
|
||||||
cx.map.insert(v.node.id, node_variant(
|
cx.map.insert(v.node.id, node_variant(
|
||||||
v, ast_util::local_def(i.id),
|
v, ast_util::local_def(i.id), extend(cx, i.ident)));
|
||||||
@(cx.path + [path_name(i.ident)])));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ { }
|
_ { }
|
||||||
}
|
}
|
||||||
alt i.node {
|
alt i.node {
|
||||||
item_mod(_) | item_native_mod(_) { cx.path += [path_mod(i.ident)]; }
|
item_mod(_) | item_native_mod(_) {
|
||||||
|
cx.path += [path_mod(i.ident)];
|
||||||
|
}
|
||||||
_ { cx.path += [path_name(i.ident)]; }
|
_ { cx.path += [path_name(i.ident)]; }
|
||||||
}
|
}
|
||||||
visit::visit_item(i, cx, v);
|
visit::visit_item(i, cx, v);
|
||||||
vec::pop(cx.path);
|
vec::pop(cx.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn map_view_item(vi: @view_item, cx: ctx, _v: vt) {
|
||||||
|
alt vi.node {
|
||||||
|
view_item_export(vps) {
|
||||||
|
for vp in vps {
|
||||||
|
let (id, name) = alt vp.node {
|
||||||
|
view_path_simple(nm, _, id) { (id, nm) }
|
||||||
|
view_path_glob(pth, id) | view_path_list(pth, _, id) {
|
||||||
|
(id, vec::last_total(*pth))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
cx.map.insert(id, node_export(vp, extend(cx, name)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn map_native_item(i: @native_item, cx: ctx, v: vt) {
|
fn map_native_item(i: @native_item, cx: ctx, v: vt) {
|
||||||
cx.map.insert(i.id, node_native_item(i, @cx.path));
|
cx.map.insert(i.id, node_native_item(i, @cx.path));
|
||||||
visit::visit_native_item(i, cx, v);
|
visit::visit_native_item(i, cx, v);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import front::attr;
|
||||||
import metadata::{csearch, cstore};
|
import metadata::{csearch, cstore};
|
||||||
import driver::session::session;
|
import driver::session::session;
|
||||||
import util::common::*;
|
import util::common::*;
|
||||||
import std::map::{new_int_hash, new_str_hash};
|
import std::map::{new_int_hash, new_str_hash, mk_hashmap};
|
||||||
import syntax::codemap::span;
|
import syntax::codemap::span;
|
||||||
import syntax::visit;
|
import syntax::visit;
|
||||||
import visit::vt;
|
import visit::vt;
|
||||||
|
@ -117,16 +117,18 @@ type indexed_mod = {
|
||||||
|
|
||||||
type def_map = hashmap<node_id, def>;
|
type def_map = hashmap<node_id, def>;
|
||||||
type ext_map = hashmap<def_id, [ident]>;
|
type ext_map = hashmap<def_id, [ident]>;
|
||||||
type exp_map = hashmap<str, @mutable [def]>;
|
|
||||||
type impl_map = hashmap<node_id, iscopes>;
|
type impl_map = hashmap<node_id, iscopes>;
|
||||||
type impl_cache = hashmap<def_id, option<@[@_impl]>>;
|
type impl_cache = hashmap<def_id, option<@[@_impl]>>;
|
||||||
|
|
||||||
|
type exp = {reexp: bool, id: def_id};
|
||||||
|
type exp_map = hashmap<node_id, [exp]>;
|
||||||
|
|
||||||
type env =
|
type env =
|
||||||
{cstore: cstore::cstore,
|
{cstore: cstore::cstore,
|
||||||
def_map: def_map,
|
def_map: def_map,
|
||||||
ast_map: ast_map::map,
|
ast_map: ast_map::map,
|
||||||
imports: hashmap<ast::node_id, import_state>,
|
imports: hashmap<ast::node_id, import_state>,
|
||||||
exp_map: exp_map,
|
mutable exp_map: exp_map,
|
||||||
mod_map: hashmap<ast::node_id, @indexed_mod>,
|
mod_map: hashmap<ast::node_id, @indexed_mod>,
|
||||||
block_map: hashmap<ast::node_id, [glob_imp_def]>,
|
block_map: hashmap<ast::node_id, [glob_imp_def]>,
|
||||||
ext_map: ext_map,
|
ext_map: ext_map,
|
||||||
|
@ -188,7 +190,7 @@ fn create_env(sess: session, amap: ast_map::map) -> @env {
|
||||||
def_map: new_int_hash(),
|
def_map: new_int_hash(),
|
||||||
ast_map: amap,
|
ast_map: amap,
|
||||||
imports: new_int_hash(),
|
imports: new_int_hash(),
|
||||||
exp_map: new_str_hash(),
|
mutable exp_map: new_int_hash(),
|
||||||
mod_map: new_int_hash(),
|
mod_map: new_int_hash(),
|
||||||
block_map: new_int_hash(),
|
block_map: new_int_hash(),
|
||||||
ext_map: new_def_hash(),
|
ext_map: new_def_hash(),
|
||||||
|
@ -2005,63 +2007,59 @@ fn check_exports(e: @env) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn lookup_glob_any(e: @env, info: @indexed_mod, sp: span, path: str,
|
fn lookup_glob_any(e: @env, info: @indexed_mod, sp: span,
|
||||||
ident: ident) -> bool {
|
ident: ident, export_id: node_id) -> bool {
|
||||||
let lookup =
|
let m = lookup_glob_in_mod(*e, info, sp, ident, ns_module, inside);
|
||||||
bind lookup_glob_in_mod(*e, info, sp, ident, _, inside);
|
let v = lookup_glob_in_mod(*e, info, sp, ident, ns_val(value_or_enum),
|
||||||
let (m, v, t) = (lookup(ns_module),
|
inside);
|
||||||
lookup(ns_val(value_or_enum)),
|
let t = lookup_glob_in_mod(*e, info, sp, ident, ns_type, inside);
|
||||||
lookup(ns_type));
|
maybe_add_reexport(e, export_id, m);
|
||||||
let full_path = path + ident;
|
maybe_add_reexport(e, export_id, v);
|
||||||
maybe_add_reexport(e, full_path, m);
|
maybe_add_reexport(e, export_id, t);
|
||||||
maybe_add_reexport(e, full_path, v);
|
|
||||||
maybe_add_reexport(e, full_path, t);
|
|
||||||
is_some(m) || is_some(v) || is_some(t)
|
is_some(m) || is_some(v) || is_some(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_add_reexport(e: @env, path: str, def: option<def>) {
|
|
||||||
alt def {
|
fn maybe_add_reexport(e: @env, export_id: node_id, def: option<def>) {
|
||||||
some(def) {
|
option::may(def) {|def|
|
||||||
alt e.exp_map.find(path) {
|
add_export(e, export_id, def_id_of_def(def), true);
|
||||||
some(v) {
|
|
||||||
// If there are multiple reexports of the same def
|
|
||||||
// using the same path, then we only need one copy
|
|
||||||
if !vec::contains(*v, def) {
|
|
||||||
*v += [def];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
none { e.exp_map.insert(path, @mutable [def]); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn add_export(e: @env, export_id: node_id, target_id: def_id,
|
||||||
|
reexp: bool) {
|
||||||
|
let found = alt e.exp_map.find(export_id) {
|
||||||
|
some(f) { f } none { [] }
|
||||||
|
};
|
||||||
|
e.exp_map.insert(export_id, found + [{reexp: reexp, id: target_id}]);
|
||||||
|
}
|
||||||
|
|
||||||
fn check_export(e: @env, ident: str, _mod: @indexed_mod,
|
fn check_export(e: @env, ident: str, _mod: @indexed_mod,
|
||||||
vi: @view_item) {
|
export_id: node_id, vi: @view_item) {
|
||||||
let found_something = false;
|
let found_something = false;
|
||||||
let full_path = _mod.path + ident;
|
|
||||||
if _mod.index.contains_key(ident) {
|
if _mod.index.contains_key(ident) {
|
||||||
found_something = true;
|
found_something = true;
|
||||||
let xs = _mod.index.get(ident);
|
let xs = _mod.index.get(ident);
|
||||||
list::iter(xs) {|x|
|
list::iter(xs) {|x|
|
||||||
alt x {
|
alt x {
|
||||||
mie_import_ident(id, _) {
|
mie_import_ident(id, _) {
|
||||||
alt e.imports.get(id) {
|
alt check e.imports.get(id) {
|
||||||
resolved(v, t, m, _, rid, _) {
|
resolved(v, t, m, _, rid, _) {
|
||||||
maybe_add_reexport(e, full_path, v);
|
maybe_add_reexport(e, export_id, v);
|
||||||
maybe_add_reexport(e, full_path, t);
|
maybe_add_reexport(e, export_id, t);
|
||||||
maybe_add_reexport(e, full_path, m);
|
maybe_add_reexport(e, export_id, m);
|
||||||
}
|
}
|
||||||
_ { }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mie_item(@{id, _}) | mie_native_item(@{id, _}) |
|
||||||
|
mie_enum_variant(_, _, id, _) {
|
||||||
|
add_export(e, export_id, local_def(id), false);
|
||||||
|
}
|
||||||
_ { }
|
_ { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
found_something |= lookup_glob_any(e, _mod, vi.span,
|
found_something |= lookup_glob_any(e, _mod, vi.span, ident,
|
||||||
_mod.path, ident);
|
export_id);
|
||||||
if !found_something {
|
if !found_something {
|
||||||
e.sess.span_warn(vi.span,
|
e.sess.span_warn(vi.span,
|
||||||
#fmt("exported item %s is not defined", ident));
|
#fmt("exported item %s is not defined", ident));
|
||||||
|
@ -2071,64 +2069,54 @@ fn check_exports(e: @env) {
|
||||||
fn check_enum_ok(e: @env, sp:span, id: ident, _mod: @indexed_mod)
|
fn check_enum_ok(e: @env, sp:span, id: ident, _mod: @indexed_mod)
|
||||||
-> node_id {
|
-> node_id {
|
||||||
alt _mod.index.find(id) {
|
alt _mod.index.find(id) {
|
||||||
none { e.sess.span_fatal(sp, #fmt("undefined id %s \
|
none {
|
||||||
in an export", id)); }
|
e.sess.span_fatal(sp, #fmt("undefined id %s in an export", id));
|
||||||
some(ms) {
|
}
|
||||||
let maybe_id = list::find(ms) {|m|
|
some(ms) {
|
||||||
alt m {
|
let maybe_id = list::find(ms) {|m|
|
||||||
mie_item(an_item) {
|
alt m {
|
||||||
alt an_item.node {
|
mie_item(@{node: item_enum(_, _), id, _}) { some(id) }
|
||||||
item_enum(_,_) { /* OK */ some(an_item.id) }
|
_ { none }
|
||||||
_ { none }
|
}
|
||||||
}
|
};
|
||||||
}
|
alt maybe_id {
|
||||||
_ { none }
|
some(an_id) { an_id }
|
||||||
}
|
_ { e.sess.span_fatal(sp, #fmt("%s does not refer \
|
||||||
};
|
to an enumeration", id)); }
|
||||||
alt maybe_id {
|
}
|
||||||
some(an_id) { ret an_id; }
|
}
|
||||||
_ { e.sess.span_fatal(sp, #fmt("%s does not refer \
|
}
|
||||||
to an enumeration", id)); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_export_enum_list(e: @env, _mod: @indexed_mod,
|
fn check_export_enum_list(e: @env, export_id: node_id, _mod: @indexed_mod,
|
||||||
span: codemap::span, id: ast::ident,
|
span: codemap::span, id: ast::ident,
|
||||||
ids: [ast::path_list_ident]) {
|
ids: [ast::path_list_ident]) {
|
||||||
if vec::len(ids) == 0u {
|
let parent_id = check_enum_ok(e, span, id, _mod);
|
||||||
let _ = check_enum_ok(e, span, id, _mod);
|
add_export(e, export_id, local_def(parent_id), false);
|
||||||
} else {
|
for variant_id in ids {
|
||||||
let parent_id = check_enum_ok(e, span, id, _mod);
|
let found = false;
|
||||||
for variant_id in ids {
|
alt _mod.index.find(variant_id.node.name) {
|
||||||
alt _mod.index.find(variant_id.node.name) {
|
some(ms) {
|
||||||
some(ms) {
|
list::iter(ms) {|m|
|
||||||
list::iter(ms) {|m|
|
alt m {
|
||||||
alt m {
|
mie_enum_variant(_, _, actual_parent_id, _) {
|
||||||
mie_enum_variant(_, _, actual_parent_id, _) {
|
found = true;
|
||||||
if actual_parent_id != parent_id {
|
if actual_parent_id != parent_id {
|
||||||
let msg = #fmt("variant %s \
|
e.sess.span_err(
|
||||||
doesn't belong to enum %s",
|
span, #fmt("variant %s doesn't belong to \
|
||||||
variant_id.node.name,
|
enum %s",
|
||||||
id);
|
variant_id.node.name, id));
|
||||||
e.sess.span_err(span, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ {
|
|
||||||
e.sess.span_err(span,
|
|
||||||
#fmt("%s is not a variant",
|
|
||||||
variant_id.node.name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
_ {}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_ {
|
|
||||||
e.sess.span_err(span,
|
|
||||||
#fmt("%s is not a variant",
|
|
||||||
variant_id.node.name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
_ {}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
e.sess.span_err(span, #fmt("%s is not a variant",
|
||||||
|
variant_id.node.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2141,17 +2129,17 @@ fn check_exports(e: @env) {
|
||||||
for vi in m.view_items {
|
for vi in m.view_items {
|
||||||
iter_export_paths(*vi) { |vp|
|
iter_export_paths(*vi) { |vp|
|
||||||
alt vp.node {
|
alt vp.node {
|
||||||
ast::view_path_simple(ident, _, _) {
|
ast::view_path_simple(ident, _, id) {
|
||||||
check_export(e, ident, _mod, vi);
|
check_export(e, ident, _mod, id, vi);
|
||||||
}
|
}
|
||||||
ast::view_path_list(path, ids, _) {
|
ast::view_path_list(path, ids, node_id) {
|
||||||
let id = if vec::len(*path) == 1u {
|
let id = if vec::len(*path) == 1u {
|
||||||
path[0]
|
path[0]
|
||||||
} else {
|
} else {
|
||||||
e.sess.span_fatal(vp.span,
|
e.sess.span_fatal(vp.span, "bad export name-list")
|
||||||
#fmt("bad export name-list"))
|
|
||||||
};
|
};
|
||||||
check_export_enum_list(e, _mod, vp.span, id, ids);
|
check_export_enum_list(e, node_id, _mod, vp.span, id,
|
||||||
|
ids);
|
||||||
}
|
}
|
||||||
ast::view_path_glob(_, node_id) {
|
ast::view_path_glob(_, node_id) {
|
||||||
glob_is_re_exported.insert(node_id, ());
|
glob_is_re_exported.insert(node_id, ());
|
||||||
|
@ -2162,18 +2150,14 @@ fn check_exports(e: @env) {
|
||||||
// Now follow the export-glob links and fill in the
|
// Now follow the export-glob links and fill in the
|
||||||
// globbed_exports and exp_map lists.
|
// globbed_exports and exp_map lists.
|
||||||
for glob in _mod.glob_imports {
|
for glob in _mod.glob_imports {
|
||||||
alt check glob.path.node {
|
let id = alt check glob.path.node {
|
||||||
ast::view_path_glob(path, node_id) {
|
ast::view_path_glob(_, node_id) { node_id }
|
||||||
if ! glob_is_re_exported.contains_key(node_id) {
|
};
|
||||||
cont;
|
if ! glob_is_re_exported.contains_key(id) { cont; }
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iter_mod(*e, glob.def,
|
iter_mod(*e, glob.def,
|
||||||
glob.path.span, outside) {|ident, def|
|
glob.path.span, outside) {|ident, def|
|
||||||
let full_path = _mod.path + ident;
|
|
||||||
_mod.globbed_exports += [ident];
|
_mod.globbed_exports += [ident];
|
||||||
maybe_add_reexport(e, full_path, some(def));
|
maybe_add_reexport(e, id, some(def));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2216,7 +2216,8 @@ fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_map::node_expr(_) | ast_map::node_arg(_, _) |
|
ast_map::node_expr(_) | ast_map::node_arg(_, _) |
|
||||||
ast_map::node_local(_) | ast_map::node_res_ctor(_) {
|
ast_map::node_local(_) | ast_map::node_res_ctor(_) |
|
||||||
|
ast_map::node_export(_, _) {
|
||||||
cx.sess.bug(#fmt["cannot find item_path for node %?", node]);
|
cx.sess.bug(#fmt["cannot find item_path for node %?", node]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import std::map;
|
||||||
import rustc::syntax::ast;
|
import rustc::syntax::ast;
|
||||||
import rustc::syntax::ast_util;
|
import rustc::syntax::ast_util;
|
||||||
import rustc::util::common;
|
import rustc::util::common;
|
||||||
|
import rustc::middle::ast_map;
|
||||||
|
|
||||||
export mk_pass;
|
export mk_pass;
|
||||||
|
|
||||||
|
@ -75,10 +76,11 @@ fn from_str_assoc_list<V:copy>(
|
||||||
fn build_reexport_def_set(srv: astsrv::srv) -> def_set {
|
fn build_reexport_def_set(srv: astsrv::srv) -> def_set {
|
||||||
let assoc_list = astsrv::exec(srv) {|ctxt|
|
let assoc_list = astsrv::exec(srv) {|ctxt|
|
||||||
let def_set = common::new_def_hash();
|
let def_set = common::new_def_hash();
|
||||||
ctxt.exp_map.items {|_path, defs|
|
ctxt.exp_map.items {|_id, defs|
|
||||||
for def in *defs {
|
for def in defs {
|
||||||
let def_id = ast_util::def_id_of_def(def);
|
if def.reexp {
|
||||||
def_set.insert(def_id, ());
|
def_set.insert(def.id, ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
to_assoc_list(def_set)
|
to_assoc_list(def_set)
|
||||||
|
@ -154,29 +156,32 @@ fn build_reexport_path_map(srv: astsrv::srv, -def_map: def_map) -> path_map {
|
||||||
let def_map = from_def_assoc_list(def_assoc_list);
|
let def_map = from_def_assoc_list(def_assoc_list);
|
||||||
let path_map = map::new_str_hash();
|
let path_map = map::new_str_hash();
|
||||||
|
|
||||||
ctxt.exp_map.items {|path, defs|
|
ctxt.exp_map.items {|exp_id, defs|
|
||||||
|
let path = alt check ctxt.ast_map.get(exp_id) {
|
||||||
let path = str::split_str(path, "::");
|
ast_map::node_export(_, path) { path }
|
||||||
let modpath = str::connect(vec::init(path), "::");
|
};
|
||||||
let name = option::get(vec::last(path));
|
let name = alt check vec::last_total(*path) {
|
||||||
|
ast_map::path_name(nm) { nm }
|
||||||
|
};
|
||||||
|
let modpath = ast_map::path_to_str(vec::init(*path));
|
||||||
|
|
||||||
let reexportdocs = [];
|
let reexportdocs = [];
|
||||||
for def in *defs {
|
for def in defs {
|
||||||
let def_id = ast_util::def_id_of_def(def);
|
if !def.reexp { cont; }
|
||||||
alt def_map.find(def_id) {
|
alt def_map.find(def.id) {
|
||||||
some(itemtag) {
|
some(itemtag) {
|
||||||
reexportdocs += [(name, itemtag)];
|
reexportdocs += [(name, itemtag)];
|
||||||
}
|
}
|
||||||
none { }
|
_ {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if vec::is_not_empty(reexportdocs) {
|
if reexportdocs.len() > 0u {
|
||||||
let prevdocs = alt path_map.find(modpath) {
|
option::may(path_map.find(modpath)) {|docs|
|
||||||
some(docs) { docs }
|
reexportdocs = docs + vec::filter(reexportdocs, {|x|
|
||||||
none { [] }
|
!vec::contains(docs, x)
|
||||||
};
|
});
|
||||||
let reexportdocs = prevdocs + reexportdocs;
|
}
|
||||||
path_map.insert(modpath, reexportdocs);
|
path_map.insert(modpath, reexportdocs);
|
||||||
#debug("path_map entry: %? - %?",
|
#debug("path_map entry: %? - %?",
|
||||||
modpath, (name, reexportdocs));
|
modpath, (name, reexportdocs));
|
||||||
|
|
Loading…
Reference in New Issue