rustc: Get tag variants from the crate metadata
This commit is contained in:
parent
ec9d7abf8c
commit
6dc452335a
@ -8,6 +8,7 @@ import lib.llvm.mk_object_file;
|
||||
import lib.llvm.mk_section_iter;
|
||||
import middle.fold;
|
||||
import middle.metadata;
|
||||
import middle.trans;
|
||||
import middle.ty;
|
||||
import back.x86;
|
||||
import util.common;
|
||||
@ -324,7 +325,8 @@ impure fn move_to_item(&ebml.reader ebml_r, int item_id) {
|
||||
auto eqer = bind eq_item(_, item_id);
|
||||
auto hash = metadata.hash_def_num(item_id);
|
||||
ebml.move_to_sibling_with_id(ebml_r, metadata.tag_items);
|
||||
lookup_hash_entry(ebml_r, eqer, hash);
|
||||
auto found = lookup_hash_entry(ebml_r, eqer, hash);
|
||||
check (found);
|
||||
}
|
||||
|
||||
// Looks up an item in the given metadata and returns an EBML reader pointing
|
||||
@ -409,17 +411,17 @@ impure fn get_item_type(&ebml.reader ebml_r, int this_cnum) -> @ty.t {
|
||||
ret get_item_generic[@ty.t](ebml_r, metadata.tag_items_data_item_type, f);
|
||||
}
|
||||
|
||||
impure fn get_item_ty_params(&ebml.reader ebml_r, int this_cnum)
|
||||
impure fn collect_def_ids(&ebml.reader ebml_r, int this_cnum, uint tag_id)
|
||||
-> vec[ast.def_id] {
|
||||
let vec[ast.def_id] tps = vec();
|
||||
let vec[ast.def_id] def_ids = vec();
|
||||
while (ebml.bytes_left(ebml_r) > 0u) {
|
||||
auto ebml_tag = ebml.peek(ebml_r);
|
||||
if (ebml_tag.id == metadata.tag_items_data_item_ty_param) {
|
||||
if (ebml_tag.id == tag_id) {
|
||||
ebml.move_to_first_child(ebml_r);
|
||||
|
||||
auto data = ebml.read_data(ebml_r);
|
||||
auto external_def_id = parse_def_id(data);
|
||||
tps += vec(tup(this_cnum, external_def_id._1));
|
||||
def_ids += vec(tup(this_cnum, external_def_id._1));
|
||||
|
||||
ebml.move_to_parent(ebml_r);
|
||||
}
|
||||
@ -430,7 +432,19 @@ impure fn get_item_ty_params(&ebml.reader ebml_r, int this_cnum)
|
||||
ebml.move_to_parent(ebml_r);
|
||||
ebml.move_to_first_child(ebml_r);
|
||||
|
||||
ret tps;
|
||||
ret def_ids;
|
||||
}
|
||||
|
||||
impure fn get_item_ty_params(&ebml.reader ebml_r, int this_cnum)
|
||||
-> vec[ast.def_id] {
|
||||
ret collect_def_ids(ebml_r, this_cnum,
|
||||
metadata.tag_items_data_item_ty_param);
|
||||
}
|
||||
|
||||
impure fn collect_tag_variant_ids(&ebml.reader ebml_r, int this_cnum)
|
||||
-> vec[ast.def_id] {
|
||||
ret collect_def_ids(ebml_r, this_cnum,
|
||||
metadata.tag_items_data_item_variant);
|
||||
}
|
||||
|
||||
|
||||
@ -590,6 +604,35 @@ fn get_symbol(session.session sess, ast.def_id def) -> str {
|
||||
ret get_item_symbol(ebml_r);
|
||||
}
|
||||
|
||||
fn get_tag_variants(session.session sess, ast.def_id def)
|
||||
-> vec[trans.variant_info] {
|
||||
auto external_crate_id = def._0;
|
||||
auto data = sess.get_external_crate(external_crate_id);
|
||||
auto ebml_r = lookup_item(def._1, data);
|
||||
|
||||
let vec[trans.variant_info] infos = vec();
|
||||
auto variant_ids = collect_tag_variant_ids(ebml_r, external_crate_id);
|
||||
for (ast.def_id did in variant_ids) {
|
||||
ebml.reset_reader(ebml_r, 0u);
|
||||
move_to_item(ebml_r, did._1);
|
||||
auto ctor_ty = get_item_type(ebml_r, external_crate_id);
|
||||
let vec[@ty.t] arg_tys = vec();
|
||||
alt (ctor_ty.struct) {
|
||||
case (ty.ty_fn(_, ?args, _)) {
|
||||
for (ty.arg a in args) {
|
||||
arg_tys += vec(a.ty);
|
||||
}
|
||||
}
|
||||
case (_) {
|
||||
// Nullary tag variant.
|
||||
}
|
||||
}
|
||||
infos += vec(rec(args=arg_tys, ctor_ty=ctor_ty, id=did));
|
||||
}
|
||||
|
||||
ret infos;
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
// fill-column: 78;
|
||||
|
@ -176,8 +176,12 @@ fn encode_def_id(&ebml.writer ebml_w, &ast.def_id id) {
|
||||
ebml.end_tag(ebml_w);
|
||||
}
|
||||
|
||||
fn encode_tag_variant_paths(&ebml.writer ebml_w, vec[ast.variant] variants) {
|
||||
fn encode_tag_variant_paths(&ebml.writer ebml_w,
|
||||
vec[ast.variant] variants,
|
||||
vec[str] path,
|
||||
&mutable vec[tup(str, uint)] index) {
|
||||
for (ast.variant variant in variants) {
|
||||
add_to_index(ebml_w, path, index, variant.node.name);
|
||||
ebml.start_tag(ebml_w, tag_paths_data_item);
|
||||
encode_name(ebml_w, variant.node.name);
|
||||
encode_def_id(ebml_w, variant.node.id);
|
||||
@ -266,9 +270,10 @@ fn encode_module_item_paths(&ebml.writer ebml_w,
|
||||
add_to_index(ebml_w, path, index, id);
|
||||
ebml.start_tag(ebml_w, tag_paths_data_item);
|
||||
encode_name(ebml_w, id);
|
||||
encode_tag_variant_paths(ebml_w, variants);
|
||||
encode_def_id(ebml_w, did);
|
||||
ebml.end_tag(ebml_w);
|
||||
|
||||
encode_tag_variant_paths(ebml_w, variants, path, index);
|
||||
}
|
||||
case (ast.item_obj(?id, _, ?tps, ?odid, ?ann)) {
|
||||
add_to_index(ebml_w, path, index, id);
|
||||
@ -314,6 +319,12 @@ fn encode_type_params(&ebml.writer ebml_w, vec[ast.ty_param] tps) {
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_variant_id(&ebml.writer ebml_w, ast.def_id vid) {
|
||||
ebml.start_tag(ebml_w, tag_items_data_item_variant);
|
||||
ebml_w.writer.write(_str.bytes(def_to_str(vid)));
|
||||
ebml.end_tag(ebml_w);
|
||||
}
|
||||
|
||||
fn encode_type(&ebml.writer ebml_w, @ty.t typ) {
|
||||
ebml.start_tag(ebml_w, tag_items_data_item_type);
|
||||
auto f = def_to_str;
|
||||
@ -348,23 +359,24 @@ fn encode_obj_type_id(&ebml.writer ebml_w, &ast.def_id id) {
|
||||
|
||||
|
||||
fn encode_tag_variant_info(@trans.crate_ctxt cx, &ebml.writer ebml_w,
|
||||
ast.def_id did, vec[ast.variant] variants) {
|
||||
ast.def_id did, vec[ast.variant] variants,
|
||||
&mutable vec[tup(int, uint)] index) {
|
||||
for (ast.variant variant in variants) {
|
||||
index += vec(tup(variant.node.id._1, ebml_w.writer.tell()));
|
||||
|
||||
ebml.start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, variant.node.id);
|
||||
encode_kind(ebml_w, 'v' as u8);
|
||||
encode_tag_id(ebml_w, did);
|
||||
encode_type(ebml_w, trans.node_ann_type(cx, variant.node.ann));
|
||||
if (_vec.len[ast.variant_arg](variant.node.args) > 0u) {
|
||||
encode_symbol(cx, ebml_w, variant.node.id);
|
||||
}
|
||||
encode_discriminant(cx, ebml_w, variant.node.id);
|
||||
ebml.end_tag(ebml_w);
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_info_for_item(@trans.crate_ctxt cx, &ebml.writer ebml_w,
|
||||
@ast.item item) {
|
||||
@ast.item item, &mutable vec[tup(int, uint)] index) {
|
||||
alt (item.node) {
|
||||
case (ast.item_const(_, _, _, ?did, ?ann)) {
|
||||
ebml.start_tag(ebml_w, tag_items_data_item);
|
||||
@ -409,9 +421,12 @@ fn encode_info_for_item(@trans.crate_ctxt cx, &ebml.writer ebml_w,
|
||||
encode_kind(ebml_w, 't' as u8);
|
||||
encode_type_params(ebml_w, tps);
|
||||
encode_type(ebml_w, trans.node_ann_type(cx, ann));
|
||||
for (ast.variant v in variants) {
|
||||
encode_variant_id(ebml_w, v.node.id);
|
||||
}
|
||||
ebml.end_tag(ebml_w);
|
||||
|
||||
encode_tag_variant_info(cx, ebml_w, did, variants);
|
||||
encode_tag_variant_info(cx, ebml_w, did, variants, index);
|
||||
}
|
||||
case (ast.item_obj(?id, _, ?tps, ?odid, ?ann)) {
|
||||
ebml.start_tag(ebml_w, tag_items_data_item);
|
||||
@ -458,7 +473,7 @@ fn encode_info_for_items(@trans.crate_ctxt cx, &ebml.writer ebml_w)
|
||||
ebml.start_tag(ebml_w, tag_items_data);
|
||||
for each (@tup(ast.def_id, @ast.item) kvp in cx.items.items()) {
|
||||
index += vec(tup(kvp._0._1, ebml_w.writer.tell()));
|
||||
encode_info_for_item(cx, ebml_w, kvp._1);
|
||||
encode_info_for_item(cx, ebml_w, kvp._1, index);
|
||||
}
|
||||
for each (@tup(ast.def_id, @ast.native_item) kvp in
|
||||
cx.native_items.items()) {
|
||||
|
@ -1911,7 +1911,10 @@ type variant_info = rec(vec[@ty.t] args, @ty.t ctor_ty, ast.def_id id);
|
||||
|
||||
// Returns information about the variants in a tag.
|
||||
fn tag_variants(@crate_ctxt cx, ast.def_id id) -> vec[variant_info] {
|
||||
// FIXME: This doesn't work for external variants.
|
||||
if (cx.sess.get_targ_crate_num() != id._0) {
|
||||
ret creader.get_tag_variants(cx.sess, id);
|
||||
}
|
||||
|
||||
check (cx.items.contains_key(id));
|
||||
alt (cx.items.get(id).node) {
|
||||
case (ast.item_tag(_, ?variants, _, _, _)) {
|
||||
|
@ -47,6 +47,7 @@ auth front.creader.load_crate = unsafe;
|
||||
auth front.creader.lookup_def = impure;
|
||||
auth front.creader.get_type = impure;
|
||||
auth front.creader.get_symbol = impure;
|
||||
auth front.creader.get_tag_variants = impure;
|
||||
auth front.creader.impure_no_op = impure;
|
||||
auth middle.metadata = unsafe;
|
||||
auth middle.metadata.encode_index = impure;
|
||||
|
Loading…
Reference in New Issue
Block a user