2011-05-14 19:02:30 -07:00
|
|
|
import std::_vec;
|
|
|
|
import std::option;
|
|
|
|
import std::option::some;
|
|
|
|
import std::option::none;
|
|
|
|
|
|
|
|
import front::ast;
|
|
|
|
|
|
|
|
import front::ast::ident;
|
|
|
|
import front::ast::def_id;
|
|
|
|
import front::ast::ann;
|
|
|
|
import front::ast::item;
|
|
|
|
import front::ast::_fn;
|
|
|
|
import front::ast::_mod;
|
|
|
|
import front::ast::crate;
|
|
|
|
import front::ast::_obj;
|
|
|
|
import front::ast::ty_param;
|
|
|
|
import front::ast::item_fn;
|
|
|
|
import front::ast::item_obj;
|
|
|
|
import front::ast::item_ty;
|
|
|
|
import front::ast::item_tag;
|
|
|
|
import front::ast::item_const;
|
|
|
|
import front::ast::item_mod;
|
|
|
|
import front::ast::item_native_mod;
|
|
|
|
import front::ast::expr;
|
|
|
|
import front::ast::elt;
|
|
|
|
import front::ast::field;
|
|
|
|
import front::ast::decl;
|
|
|
|
import front::ast::decl_local;
|
|
|
|
import front::ast::decl_item;
|
|
|
|
import front::ast::initializer;
|
|
|
|
import front::ast::local;
|
|
|
|
import front::ast::arm;
|
|
|
|
import front::ast::expr_call;
|
|
|
|
import front::ast::expr_vec;
|
|
|
|
import front::ast::expr_tup;
|
|
|
|
import front::ast::expr_path;
|
|
|
|
import front::ast::expr_field;
|
|
|
|
import front::ast::expr_index;
|
|
|
|
import front::ast::expr_log;
|
|
|
|
import front::ast::expr_block;
|
|
|
|
import front::ast::expr_rec;
|
|
|
|
import front::ast::expr_if;
|
|
|
|
import front::ast::expr_binary;
|
|
|
|
import front::ast::expr_unary;
|
|
|
|
import front::ast::expr_assign;
|
|
|
|
import front::ast::expr_assign_op;
|
|
|
|
import front::ast::expr_while;
|
|
|
|
import front::ast::expr_do_while;
|
|
|
|
import front::ast::expr_alt;
|
|
|
|
import front::ast::expr_lit;
|
|
|
|
import front::ast::expr_ret;
|
|
|
|
import front::ast::expr_self_method;
|
|
|
|
import front::ast::expr_bind;
|
|
|
|
import front::ast::expr_spawn;
|
|
|
|
import front::ast::expr_ext;
|
|
|
|
import front::ast::expr_fail;
|
|
|
|
import front::ast::expr_break;
|
|
|
|
import front::ast::expr_cont;
|
|
|
|
import front::ast::expr_send;
|
|
|
|
import front::ast::expr_recv;
|
|
|
|
import front::ast::expr_put;
|
|
|
|
import front::ast::expr_port;
|
|
|
|
import front::ast::expr_chan;
|
|
|
|
import front::ast::expr_be;
|
|
|
|
import front::ast::expr_check;
|
|
|
|
import front::ast::expr_assert;
|
|
|
|
import front::ast::expr_cast;
|
|
|
|
import front::ast::expr_for;
|
|
|
|
import front::ast::expr_for_each;
|
|
|
|
import front::ast::stmt;
|
|
|
|
import front::ast::stmt_decl;
|
|
|
|
import front::ast::stmt_expr;
|
|
|
|
import front::ast::block;
|
|
|
|
import front::ast::block_;
|
|
|
|
import front::ast::method;
|
|
|
|
|
|
|
|
import middle::fold;
|
|
|
|
import middle::fold::respan;
|
|
|
|
import middle::fold::new_identity_fold;
|
|
|
|
import middle::fold::fold_crate;
|
|
|
|
import middle::fold::fold_item;
|
|
|
|
import middle::fold::fold_method;
|
|
|
|
|
|
|
|
import util::common::uistr;
|
|
|
|
import util::common::span;
|
|
|
|
import util::common::new_str_hash;
|
|
|
|
|
|
|
|
import middle::tstate::aux::fn_info;
|
|
|
|
import middle::tstate::aux::fn_info_map;
|
|
|
|
import middle::tstate::aux::num_locals;
|
|
|
|
import middle::tstate::aux::init_ann;
|
|
|
|
import middle::tstate::aux::init_blank_ann;
|
|
|
|
import middle::tstate::aux::get_fn_info;
|
|
|
|
|
|
|
|
fn item_fn_anns(&fn_info_map fm, &span sp, ident i, &_fn f,
|
|
|
|
vec[ty_param] ty_params, def_id id, ann a) -> @item {
|
|
|
|
|
|
|
|
assert (fm.contains_key(id));
|
|
|
|
auto f_info = fm.get(id);
|
|
|
|
|
|
|
|
log(i + " has " + uistr(num_locals(f_info)) + " local vars");
|
|
|
|
|
|
|
|
auto fld0 = new_identity_fold[fn_info]();
|
|
|
|
|
|
|
|
fld0 = @rec(fold_ann = bind init_ann(_,_)
|
|
|
|
with *fld0);
|
|
|
|
|
|
|
|
ret fold_item[fn_info]
|
|
|
|
(f_info, fld0, @respan(sp, item_fn(i, f, ty_params, id, a)));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: rewrite this with walk instead of fold */
|
|
|
|
|
|
|
|
/* This is painstakingly written as an explicit recursion b/c the
|
|
|
|
standard ast.fold doesn't traverse in the correct order:
|
|
|
|
consider
|
|
|
|
fn foo() {
|
|
|
|
fn bar() {
|
|
|
|
auto x = 5;
|
|
|
|
log(x);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
With fold, first bar() would be processed and its subexps would
|
|
|
|
correctly be annotated with length-1 bit vectors.
|
|
|
|
But then, the process would be repeated with (fn bar()...) as
|
|
|
|
a subexp of foo, which has 0 local variables -- so then
|
|
|
|
the body of bar() would be incorrectly annotated with length-0 bit
|
|
|
|
vectors. */
|
|
|
|
fn annotate_exprs(&fn_info_map fm, &vec[@expr] es) -> vec[@expr] {
|
|
|
|
fn one(fn_info_map fm, &@expr e) -> @expr {
|
|
|
|
ret annotate_expr(fm, e);
|
|
|
|
}
|
|
|
|
auto f = bind one(fm,_);
|
|
|
|
ret _vec::map[@expr, @expr](f, es);
|
|
|
|
}
|
|
|
|
fn annotate_elts(&fn_info_map fm, &vec[elt] es) -> vec[elt] {
|
|
|
|
fn one(fn_info_map fm, &elt e) -> elt {
|
|
|
|
ret rec(mut=e.mut,
|
|
|
|
expr=annotate_expr(fm, e.expr));
|
|
|
|
}
|
|
|
|
auto f = bind one(fm,_);
|
|
|
|
ret _vec::map[elt, elt](f, es);
|
|
|
|
}
|
|
|
|
fn annotate_fields(&fn_info_map fm, &vec[field] fs) -> vec[field] {
|
|
|
|
fn one(fn_info_map fm, &field f) -> field {
|
|
|
|
ret rec(mut=f.mut,
|
|
|
|
ident=f.ident,
|
|
|
|
expr=annotate_expr(fm, f.expr));
|
|
|
|
}
|
|
|
|
auto f = bind one(fm,_);
|
|
|
|
ret _vec::map[field, field](f, fs);
|
|
|
|
}
|
|
|
|
fn annotate_option_exp(&fn_info_map fm, &option::t[@expr] o)
|
|
|
|
-> option::t[@expr] {
|
|
|
|
fn one(fn_info_map fm, &@expr e) -> @expr {
|
|
|
|
ret annotate_expr(fm, e);
|
|
|
|
}
|
|
|
|
auto f = bind one(fm,_);
|
|
|
|
ret option::map[@expr, @expr](f, o);
|
|
|
|
}
|
|
|
|
fn annotate_option_exprs(&fn_info_map fm, &vec[option::t[@expr]] es)
|
|
|
|
-> vec[option::t[@expr]] {
|
|
|
|
fn one(fn_info_map fm, &option::t[@expr] o) -> option::t[@expr] {
|
|
|
|
ret annotate_option_exp(fm, o);
|
|
|
|
}
|
|
|
|
auto f = bind one(fm,_);
|
|
|
|
ret _vec::map[option::t[@expr], option::t[@expr]](f, es);
|
|
|
|
}
|
|
|
|
fn annotate_decl(&fn_info_map fm, &@decl d) -> @decl {
|
|
|
|
auto d1 = d.node;
|
|
|
|
alt (d.node) {
|
|
|
|
case (decl_local(?l)) {
|
|
|
|
alt(l.init) {
|
|
|
|
case (some[initializer](?init)) {
|
|
|
|
let option::t[initializer] an_i =
|
|
|
|
some[initializer]
|
|
|
|
(rec(expr=annotate_expr(fm, init.expr)
|
|
|
|
with init));
|
|
|
|
let @local new_l = @rec(init=an_i with *l);
|
|
|
|
d1 = decl_local(new_l);
|
|
|
|
}
|
|
|
|
case (_) { /* do nothing */ }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case (decl_item(?item)) {
|
|
|
|
d1 = decl_item(annotate_item(fm, item));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret @respan(d.span, d1);
|
|
|
|
}
|
|
|
|
fn annotate_alts(&fn_info_map fm, &vec[arm] alts) -> vec[arm] {
|
|
|
|
fn one(fn_info_map fm, &arm a) -> arm {
|
|
|
|
ret rec(pat=a.pat,
|
|
|
|
block=annotate_block(fm, a.block));
|
|
|
|
}
|
|
|
|
auto f = bind one(fm,_);
|
|
|
|
ret _vec::map[arm, arm](f, alts);
|
|
|
|
|
|
|
|
}
|
|
|
|
fn annotate_expr(&fn_info_map fm, &@expr e) -> @expr {
|
|
|
|
auto e1 = e.node;
|
|
|
|
alt (e.node) {
|
|
|
|
case (expr_vec(?es, ?m, ?a)) {
|
|
|
|
e1 = expr_vec(annotate_exprs(fm, es), m, a);
|
|
|
|
}
|
|
|
|
case (expr_tup(?es, ?a)) {
|
|
|
|
e1 = expr_tup(annotate_elts(fm, es), a);
|
|
|
|
}
|
|
|
|
case (expr_rec(?fs, ?maybe_e, ?a)) {
|
|
|
|
e1 = expr_rec(annotate_fields(fm, fs),
|
|
|
|
annotate_option_exp(fm, maybe_e), a);
|
|
|
|
}
|
|
|
|
case (expr_call(?e, ?es, ?a)) {
|
|
|
|
e1 = expr_call(annotate_expr(fm, e),
|
|
|
|
annotate_exprs(fm, es), a);
|
|
|
|
}
|
|
|
|
case (expr_self_method(_,_)) {
|
|
|
|
// no change
|
|
|
|
}
|
|
|
|
case (expr_bind(?e, ?maybe_es, ?a)) {
|
|
|
|
e1 = expr_bind(annotate_expr(fm, e),
|
|
|
|
annotate_option_exprs(fm, maybe_es),
|
|
|
|
a);
|
|
|
|
}
|
|
|
|
case (expr_spawn(?s, ?maybe_s, ?e, ?es, ?a)) {
|
|
|
|
e1 = expr_spawn(s, maybe_s, annotate_expr(fm, e),
|
|
|
|
annotate_exprs(fm, es), a);
|
|
|
|
}
|
|
|
|
case (expr_binary(?bop, ?w, ?x, ?a)) {
|
|
|
|
e1 = expr_binary(bop, annotate_expr(fm, w),
|
|
|
|
annotate_expr(fm, x), a);
|
|
|
|
}
|
|
|
|
case (expr_unary(?uop, ?w, ?a)) {
|
|
|
|
e1 = expr_unary(uop, annotate_expr(fm, w), a);
|
|
|
|
}
|
|
|
|
case (expr_lit(_,_)) {
|
|
|
|
/* no change */
|
|
|
|
}
|
|
|
|
case (expr_cast(?e,?t,?a)) {
|
|
|
|
e1 = expr_cast(annotate_expr(fm, e), t, a);
|
|
|
|
}
|
|
|
|
case (expr_if(?e, ?b, ?maybe_e, ?a)) {
|
|
|
|
e1 = expr_if(annotate_expr(fm, e),
|
|
|
|
annotate_block(fm, b),
|
|
|
|
annotate_option_exp(fm, maybe_e), a);
|
|
|
|
}
|
|
|
|
case (expr_while(?e, ?b, ?a)) {
|
|
|
|
e1 = expr_while(annotate_expr(fm, e),
|
|
|
|
annotate_block(fm, b), a);
|
|
|
|
}
|
|
|
|
case (expr_for(?d, ?e, ?b, ?a)) {
|
|
|
|
e1 = expr_for(annotate_decl(fm, d),
|
|
|
|
annotate_expr(fm, e),
|
|
|
|
annotate_block(fm, b), a);
|
|
|
|
}
|
|
|
|
case (expr_for_each(?d, ?e, ?b, ?a)) {
|
|
|
|
e1 = expr_for_each(annotate_decl(fm, d),
|
|
|
|
annotate_expr(fm, e),
|
|
|
|
annotate_block(fm, b), a);
|
|
|
|
}
|
|
|
|
case (expr_do_while(?b, ?e, ?a)) {
|
|
|
|
e1 = expr_do_while(annotate_block(fm, b),
|
|
|
|
annotate_expr(fm, e), a);
|
|
|
|
}
|
|
|
|
case (expr_alt(?e, ?alts, ?a)) {
|
|
|
|
e1 = expr_alt(annotate_expr(fm, e),
|
|
|
|
annotate_alts(fm, alts), a);
|
|
|
|
}
|
|
|
|
case (expr_block(?b, ?a)) {
|
|
|
|
e1 = expr_block(annotate_block(fm, b), a);
|
|
|
|
}
|
|
|
|
case (expr_assign(?l, ?r, ?a)) {
|
|
|
|
e1 = expr_assign(annotate_expr(fm, l), annotate_expr(fm, r), a);
|
|
|
|
}
|
|
|
|
case (expr_assign_op(?bop, ?l, ?r, ?a)) {
|
|
|
|
e1 = expr_assign_op(bop,
|
|
|
|
annotate_expr(fm, l), annotate_expr(fm, r), a);
|
|
|
|
}
|
|
|
|
case (expr_send(?l, ?r, ?a)) {
|
|
|
|
e1 = expr_send(annotate_expr(fm, l),
|
|
|
|
annotate_expr(fm, r), a);
|
|
|
|
}
|
|
|
|
case (expr_recv(?l, ?r, ?a)) {
|
|
|
|
e1 = expr_recv(annotate_expr(fm, l),
|
|
|
|
annotate_expr(fm, r), a);
|
|
|
|
}
|
|
|
|
case (expr_field(?e, ?i, ?a)) {
|
|
|
|
e1 = expr_field(annotate_expr(fm, e),
|
|
|
|
i, a);
|
|
|
|
}
|
|
|
|
case (expr_index(?e, ?sub, ?a)) {
|
|
|
|
e1 = expr_index(annotate_expr(fm, e),
|
|
|
|
annotate_expr(fm, sub), a);
|
|
|
|
}
|
|
|
|
case (expr_path(_,_)) {
|
|
|
|
/* no change */
|
|
|
|
}
|
|
|
|
case (expr_ext(?p, ?es, ?s_opt, ?e, ?a)) {
|
|
|
|
e1 = expr_ext(p, annotate_exprs(fm, es),
|
|
|
|
s_opt,
|
|
|
|
annotate_expr(fm, e), a);
|
|
|
|
}
|
|
|
|
/* no change, next 3 cases */
|
|
|
|
case (expr_fail(_)) { }
|
|
|
|
case (expr_break(_)) { }
|
|
|
|
case (expr_cont(_)) { }
|
|
|
|
case (expr_ret(?maybe_e, ?a)) {
|
|
|
|
e1 = expr_ret(annotate_option_exp(fm, maybe_e), a);
|
|
|
|
}
|
|
|
|
case (expr_put(?maybe_e, ?a)) {
|
|
|
|
e1 = expr_put(annotate_option_exp(fm, maybe_e), a);
|
|
|
|
}
|
|
|
|
case (expr_be(?e, ?a)) {
|
|
|
|
e1 = expr_be(annotate_expr(fm, e), a);
|
|
|
|
}
|
|
|
|
case (expr_log(?n, ?e, ?a)) {
|
|
|
|
e1 = expr_log(n, annotate_expr(fm, e), a);
|
|
|
|
}
|
|
|
|
case (expr_assert(?e, ?a)) {
|
|
|
|
e1 = expr_assert(annotate_expr(fm, e), a);
|
|
|
|
}
|
|
|
|
case (expr_check(?e, ?a)) {
|
|
|
|
e1 = expr_check(annotate_expr(fm, e), a);
|
|
|
|
}
|
|
|
|
case (expr_port(_)) { /* no change */ }
|
|
|
|
case (expr_chan(?e, ?a)) {
|
|
|
|
e1 = expr_chan(annotate_expr(fm, e), a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret @respan(e.span, e1);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn annotate_stmt(&fn_info_map fm, &@stmt s) -> @stmt {
|
|
|
|
alt (s.node) {
|
|
|
|
case (stmt_decl(?d, ?a)) {
|
|
|
|
ret @respan(s.span, stmt_decl(annotate_decl(fm, d), a));
|
|
|
|
}
|
|
|
|
case (stmt_expr(?e, ?a)) {
|
|
|
|
ret @respan(s.span, stmt_expr(annotate_expr(fm, e), a));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn annotate_block(&fn_info_map fm, &block b) -> block {
|
2011-05-16 19:04:45 -07:00
|
|
|
let vec[@stmt] new_stmts = [];
|
2011-05-14 19:02:30 -07:00
|
|
|
|
|
|
|
for (@stmt s in b.node.stmts) {
|
|
|
|
auto new_s = annotate_stmt(fm, s);
|
|
|
|
_vec::push[@stmt](new_stmts, new_s);
|
|
|
|
}
|
|
|
|
fn ann_e(fn_info_map fm, &@expr e) -> @expr {
|
|
|
|
ret annotate_expr(fm, e);
|
|
|
|
}
|
|
|
|
auto f = bind ann_e(fm,_);
|
|
|
|
|
|
|
|
auto new_e = option::map[@expr, @expr](f, b.node.expr);
|
|
|
|
|
|
|
|
ret respan(b.span,
|
|
|
|
rec(stmts=new_stmts, expr=new_e with b.node));
|
|
|
|
}
|
|
|
|
fn annotate_fn(&fn_info_map fm, &_fn f) -> _fn {
|
|
|
|
// subexps have *already* been annotated based on
|
|
|
|
// f's number-of-locals
|
|
|
|
ret rec(body=annotate_block(fm, f.body) with f);
|
|
|
|
}
|
|
|
|
fn annotate_mod(&fn_info_map fm, &_mod m) -> _mod {
|
2011-05-16 19:04:45 -07:00
|
|
|
let vec[@item] new_items = [];
|
2011-05-14 19:02:30 -07:00
|
|
|
|
|
|
|
for (@item i in m.items) {
|
|
|
|
auto new_i = annotate_item(fm, i);
|
|
|
|
_vec::push[@item](new_items, new_i);
|
|
|
|
}
|
|
|
|
ret rec(items=new_items with m);
|
|
|
|
}
|
|
|
|
fn annotate_method(&fn_info_map fm, &@method m) -> @method {
|
|
|
|
auto f_info = get_fn_info(fm, m.node.id);
|
|
|
|
auto fld0 = new_identity_fold[fn_info]();
|
|
|
|
fld0 = @rec(fold_ann = bind init_ann(_,_)
|
|
|
|
with *fld0);
|
|
|
|
auto outer = fold_method[fn_info](f_info, fld0, m);
|
|
|
|
auto new_fn = annotate_fn(fm, outer.node.meth);
|
|
|
|
ret @respan(m.span,
|
|
|
|
rec(meth=new_fn with m.node));
|
|
|
|
}
|
|
|
|
|
|
|
|
fn annotate_obj(&fn_info_map fm, &_obj o) -> _obj {
|
|
|
|
fn one(fn_info_map fm, &@method m) -> @method {
|
|
|
|
ret annotate_method(fm, m);
|
|
|
|
}
|
|
|
|
auto f = bind one(fm,_);
|
|
|
|
auto new_methods = _vec::map[@method, @method](f, o.methods);
|
|
|
|
auto new_dtor = option::map[@method, @method](f, o.dtor);
|
|
|
|
ret rec(methods=new_methods, dtor=new_dtor with o);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Only annotates the components of the item recursively.
|
|
|
|
fn annotate_item_inner(&fn_info_map fm, &@item item) -> @item {
|
|
|
|
alt (item.node) {
|
|
|
|
/* FIXME can't skip this case -- exprs contain blocks contain stmts,
|
|
|
|
which contain decls */
|
|
|
|
case (item_const(_,_,_,_,_)) {
|
|
|
|
// this has already been annotated by annotate_item
|
|
|
|
ret item;
|
|
|
|
}
|
|
|
|
case (item_fn(?ident, ?ff, ?tps, ?id, ?ann)) {
|
|
|
|
ret @respan(item.span,
|
|
|
|
item_fn(ident, annotate_fn(fm, ff), tps, id, ann));
|
|
|
|
}
|
|
|
|
case (item_mod(?ident, ?mm, ?id)) {
|
|
|
|
ret @respan(item.span,
|
|
|
|
item_mod(ident, annotate_mod(fm, mm), id));
|
|
|
|
}
|
|
|
|
case (item_native_mod(?ident, ?mm, ?id)) {
|
|
|
|
ret item;
|
|
|
|
}
|
|
|
|
case (item_ty(_,_,_,_,_)) {
|
|
|
|
ret item;
|
|
|
|
}
|
|
|
|
case (item_tag(_,_,_,_,_)) {
|
|
|
|
ret item;
|
|
|
|
}
|
|
|
|
case (item_obj(?ident, ?ob, ?tps, ?odid, ?ann)) {
|
|
|
|
ret @respan(item.span,
|
|
|
|
item_obj(ident, annotate_obj(fm, ob), tps, odid, ann));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn annotate_item(&fn_info_map fm, &@item item) -> @item {
|
|
|
|
// Using a fold, recursively set all anns in this item
|
|
|
|
// to be blank.
|
|
|
|
// *Then*, call annotate_item recursively to do the right
|
|
|
|
// thing for any nested items inside this one.
|
|
|
|
|
|
|
|
alt (item.node) {
|
|
|
|
case (item_const(_,_,_,_,_)) {
|
|
|
|
auto fld0 = new_identity_fold[()]();
|
|
|
|
fld0 = @rec(fold_ann = bind init_blank_ann(_,_)
|
|
|
|
with *fld0);
|
|
|
|
ret fold_item[()]((), fld0, item);
|
|
|
|
}
|
|
|
|
case (item_fn(?i,?ff,?tps,?id,?ann)) {
|
|
|
|
auto f_info = get_fn_info(fm, id);
|
|
|
|
auto fld0 = new_identity_fold[fn_info]();
|
|
|
|
fld0 = @rec(fold_ann = bind init_ann(_,_)
|
|
|
|
with *fld0);
|
|
|
|
auto outer = fold_item[fn_info](f_info, fld0, item);
|
|
|
|
// now recurse into any nested items
|
|
|
|
ret annotate_item_inner(fm, outer);
|
|
|
|
}
|
|
|
|
case (item_mod(?i, ?mm, ?id)) {
|
|
|
|
auto fld0 = new_identity_fold[()]();
|
|
|
|
fld0 = @rec(fold_ann = bind init_blank_ann(_,_)
|
|
|
|
with *fld0);
|
|
|
|
auto outer = fold_item[()]((), fld0, item);
|
|
|
|
ret annotate_item_inner(fm, outer);
|
|
|
|
}
|
|
|
|
case (item_native_mod(?i, ?nm, ?id)) {
|
|
|
|
ret item;
|
|
|
|
}
|
|
|
|
case (item_ty(_,_,_,_,_)) {
|
|
|
|
ret item;
|
|
|
|
}
|
|
|
|
case (item_tag(_,_,_,_,_)) {
|
|
|
|
ret item;
|
|
|
|
}
|
|
|
|
case (item_obj(?i,?ob,?tps,?odid,?ann)) {
|
|
|
|
auto fld0 = new_identity_fold[()]();
|
|
|
|
fld0 = @rec(fold_ann = bind init_blank_ann(_,_)
|
|
|
|
with *fld0);
|
|
|
|
auto outer = fold_item[()]((), fld0, item);
|
|
|
|
ret annotate_item_inner(fm, outer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn annotate_module(&fn_info_map fm, &_mod module) -> _mod {
|
2011-05-16 19:04:45 -07:00
|
|
|
let vec[@item] new_items = [];
|
2011-05-14 19:02:30 -07:00
|
|
|
|
|
|
|
for (@item i in module.items) {
|
|
|
|
auto new_item = annotate_item(fm, i);
|
|
|
|
_vec::push[@item](new_items, new_item);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret rec(items = new_items with module);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn annotate_crate(&fn_info_map fm, &@crate crate) -> @crate {
|
|
|
|
ret @respan(crate.span,
|
|
|
|
rec(module = annotate_module(fm, crate.node.module)
|
|
|
|
with crate.node));
|
|
|
|
}
|