2011-06-15 13:19:50 -05:00
|
|
|
|
2011-07-05 04:48:19 -05:00
|
|
|
import ast::*;
|
|
|
|
import codemap::span;
|
2011-06-08 15:48:19 -05:00
|
|
|
|
2011-06-10 10:29:34 -05:00
|
|
|
// Context-passing AST walker. Each overridden visit method has full control
|
|
|
|
// over what happens with its node, it can do its own traversal of the node's
|
|
|
|
// children (potentially passing in different contexts to each), call
|
|
|
|
// visit::visit_* to apply the default traversal algorithm (again, it can
|
|
|
|
// override the context), or prevent deeper traversal by doing nothing.
|
|
|
|
|
2011-07-26 09:35:31 -05:00
|
|
|
// Our typesystem doesn't do circular types, so the visitor record can not
|
2012-01-19 16:24:03 -06:00
|
|
|
// hold functions that take visitors. A vt enum is used to break the cycle.
|
2012-01-19 19:56:05 -06:00
|
|
|
enum vt<E> { mk_vt(visitor<E>), }
|
2011-06-08 15:48:19 -05:00
|
|
|
|
2012-01-19 16:24:03 -06:00
|
|
|
enum fn_kind {
|
2012-01-19 19:56:05 -06:00
|
|
|
fk_item_fn(ident, [ty_param]), //< an item declared with fn()
|
2012-03-07 05:54:00 -06:00
|
|
|
fk_method(ident, [ty_param], @method),
|
2012-05-07 13:31:57 -05:00
|
|
|
fk_anon(proto, capture_clause), //< an anonymous function like fn@(...)
|
|
|
|
fk_fn_block(capture_clause), //< a block {||...}
|
2012-04-10 12:52:06 -05:00
|
|
|
fk_ctor(ident, [ty_param], node_id /* self id */,
|
2012-05-14 16:13:32 -05:00
|
|
|
def_id /* parent class id */), // class constructor
|
|
|
|
fk_dtor([ty_param], node_id /* self id */,
|
|
|
|
def_id /* parent class id */) // class destructor
|
|
|
|
|
2011-12-29 22:07:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn name_of_fn(fk: fn_kind) -> ident {
|
|
|
|
alt fk {
|
2012-06-24 17:09:57 -05:00
|
|
|
fk_item_fn(name, _) | fk_method(name, _, _)
|
2012-06-21 18:44:10 -05:00
|
|
|
| fk_ctor(name, _, _, _) { /* FIXME (#2543) */ copy name }
|
2012-06-10 02:49:59 -05:00
|
|
|
fk_anon(*) | fk_fn_block(*) { @"anon" }
|
|
|
|
fk_dtor(*) { @"drop" }
|
2011-12-29 22:07:55 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn tps_of_fn(fk: fn_kind) -> [ty_param] {
|
|
|
|
alt fk {
|
2012-06-24 17:09:57 -05:00
|
|
|
fk_item_fn(_, tps) | fk_method(_, tps, _)
|
2012-06-07 23:53:47 -05:00
|
|
|
| fk_ctor(_, tps, _, _) | fk_dtor(tps, _, _) {
|
2012-06-21 18:44:10 -05:00
|
|
|
/* FIXME (#2543) */ copy tps
|
2012-06-07 23:53:47 -05:00
|
|
|
}
|
2012-05-07 13:31:57 -05:00
|
|
|
fk_anon(*) | fk_fn_block(*) { [] }
|
2011-12-29 22:07:55 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
type visitor<E> =
|
2011-07-27 07:19:39 -05:00
|
|
|
// takes the components so that one function can be
|
|
|
|
// generic over constr and ty_constr
|
2012-01-26 10:33:12 -06:00
|
|
|
@{visit_mod: fn@(_mod, span, node_id, E, vt<E>),
|
2011-10-18 17:07:40 -05:00
|
|
|
visit_view_item: fn@(@view_item, E, vt<E>),
|
|
|
|
visit_native_item: fn@(@native_item, E, vt<E>),
|
|
|
|
visit_item: fn@(@item, E, vt<E>),
|
|
|
|
visit_local: fn@(@local, E, vt<E>),
|
|
|
|
visit_block: fn@(ast::blk, E, vt<E>),
|
|
|
|
visit_stmt: fn@(@stmt, E, vt<E>),
|
|
|
|
visit_arm: fn@(arm, E, vt<E>),
|
|
|
|
visit_pat: fn@(@pat, E, vt<E>),
|
|
|
|
visit_decl: fn@(@decl, E, vt<E>),
|
|
|
|
visit_expr: fn@(@expr, E, vt<E>),
|
|
|
|
visit_ty: fn@(@ty, E, vt<E>),
|
2012-01-04 09:37:39 -06:00
|
|
|
visit_ty_params: fn@([ty_param], E, vt<E>),
|
2011-11-30 06:38:38 -06:00
|
|
|
visit_constr: fn@(@path, span, node_id, E, vt<E>),
|
2012-01-31 21:30:40 -06:00
|
|
|
visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt<E>),
|
2012-03-28 20:50:33 -05:00
|
|
|
visit_class_item: fn@(@class_member, E, vt<E>)};
|
2011-06-08 15:48:19 -05:00
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn default_visitor<E>() -> visitor<E> {
|
2012-06-19 21:34:01 -05:00
|
|
|
ret @{visit_mod: {|a,b,c,d,e|visit_mod::<E>(a, b, c, d, e)},
|
|
|
|
visit_view_item: {|a,b,c|visit_view_item::<E>(a, b, c)},
|
|
|
|
visit_native_item: {|a,b,c|visit_native_item::<E>(a, b, c)},
|
|
|
|
visit_item: {|a,b,c|visit_item::<E>(a, b, c)},
|
|
|
|
visit_local: {|a,b,c|visit_local::<E>(a, b, c)},
|
|
|
|
visit_block: {|a,b,c|visit_block::<E>(a, b, c)},
|
|
|
|
visit_stmt: {|a,b,c|visit_stmt::<E>(a, b, c)},
|
|
|
|
visit_arm: {|a,b,c|visit_arm::<E>(a, b, c)},
|
|
|
|
visit_pat: {|a,b,c|visit_pat::<E>(a, b, c)},
|
|
|
|
visit_decl: {|a,b,c|visit_decl::<E>(a, b, c)},
|
|
|
|
visit_expr: {|a,b,c|visit_expr::<E>(a, b, c)},
|
|
|
|
visit_ty: {|a,b,c|skip_ty::<E>(a, b, c)},
|
|
|
|
visit_ty_params: {|a,b,c|visit_ty_params::<E>(a, b, c)},
|
|
|
|
visit_constr: {|a,b,c,d,e|visit_constr::<E>(a, b, c, d, e)},
|
|
|
|
visit_fn: {|a,b,c,d,e,f,g|visit_fn::<E>(a, b, c, d, e, f, g)},
|
|
|
|
visit_class_item: {|a,b,c|visit_class_item::<E>(a, b, c)}};
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_crate<E>(c: crate, e: E, v: vt<E>) {
|
2012-01-26 10:33:12 -06:00
|
|
|
v.visit_mod(c.node.module, c.span, crate_node_id, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_crate_directive<E>(cd: @crate_directive, e: E, v: vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt cd.node {
|
2011-11-21 22:31:09 -06:00
|
|
|
cdir_src_mod(_, _) { }
|
|
|
|
cdir_dir_mod(_, cdirs, _) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for cdirs.each {|cdir|
|
2011-07-27 07:19:39 -05:00
|
|
|
visit_crate_directive(cdir, e, v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cdir_view_item(vi) { v.visit_view_item(vi, e, v); }
|
|
|
|
cdir_syntax(_) { }
|
2011-06-09 08:50:20 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-26 10:33:12 -06:00
|
|
|
fn visit_mod<E>(m: _mod, _sp: span, _id: node_id, e: E, v: vt<E>) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for m.view_items.each {|vi| v.visit_view_item(vi, e, v); }
|
|
|
|
for m.items.each {|i| v.visit_item(i, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_view_item<E>(_vi: @view_item, _e: E, _v: vt<E>) { }
|
2011-06-09 08:50:20 -05:00
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_local<E>(loc: @local, e: E, v: vt<E>) {
|
2011-07-28 05:01:45 -05:00
|
|
|
v.visit_pat(loc.node.pat, e, v);
|
2011-08-10 14:51:50 -05:00
|
|
|
v.visit_ty(loc.node.ty, e, v);
|
2012-01-19 00:37:22 -06:00
|
|
|
alt loc.node.init { none { } some(i) { v.visit_expr(i.expr, e, v); } }
|
2011-06-13 19:04:15 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_item<E>(i: @item, e: E, v: vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt i.node {
|
|
|
|
item_const(t, ex) { v.visit_ty(t, e, v); v.visit_expr(ex, e, v); }
|
2011-12-22 10:49:54 -06:00
|
|
|
item_fn(decl, tp, body) {
|
2012-06-21 18:44:10 -05:00
|
|
|
v.visit_fn(fk_item_fn(/* FIXME (#2543) */ copy i.ident,
|
|
|
|
/* FIXME (#2543) */ copy tp), decl, body,
|
2012-06-07 23:53:47 -05:00
|
|
|
i.span, i.id, e, v);
|
2011-12-22 10:49:54 -06:00
|
|
|
}
|
2012-01-26 10:33:12 -06:00
|
|
|
item_mod(m) { v.visit_mod(m, i.span, i.id, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
item_native_mod(nm) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for nm.view_items.each {|vi| v.visit_view_item(vi, e, v); }
|
|
|
|
for nm.items.each {|ni| v.visit_native_item(ni, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-04-18 23:26:25 -05:00
|
|
|
item_ty(t, tps, rp) {
|
|
|
|
v.visit_ty(t, e, v);
|
|
|
|
v.visit_ty_params(tps, e, v);
|
|
|
|
}
|
|
|
|
item_enum(variants, tps, _) {
|
2012-01-04 09:37:39 -06:00
|
|
|
v.visit_ty_params(tps, e, v);
|
2012-04-06 13:01:43 -05:00
|
|
|
for variants.each {|vr|
|
|
|
|
for vr.node.args.each {|va| v.visit_ty(va.ty, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
}
|
2012-04-24 17:52:52 -05:00
|
|
|
item_impl(tps, _rp, ifce, ty, methods) {
|
2012-01-04 09:37:39 -06:00
|
|
|
v.visit_ty_params(tps, e, v);
|
2012-04-13 14:22:35 -05:00
|
|
|
option::iter(ifce, {|p| visit_path(p.path, e, v)});
|
2011-12-20 09:33:55 -06:00
|
|
|
v.visit_ty(ty, e, v);
|
2012-04-06 13:01:43 -05:00
|
|
|
for methods.each {|m|
|
2012-03-01 12:36:22 -06:00
|
|
|
visit_method_helper(m, e, v)
|
2011-12-13 06:19:56 -06:00
|
|
|
}
|
|
|
|
}
|
2012-05-14 16:13:32 -05:00
|
|
|
item_class(tps, ifaces, members, ctor, m_dtor, _) {
|
2012-01-31 21:30:40 -06:00
|
|
|
v.visit_ty_params(tps, e, v);
|
2012-04-06 13:01:43 -05:00
|
|
|
for members.each {|m|
|
2012-03-28 20:50:33 -05:00
|
|
|
v.visit_class_item(m, e, v);
|
2012-01-31 21:30:40 -06:00
|
|
|
}
|
2012-04-11 18:18:00 -05:00
|
|
|
for ifaces.each {|p| visit_path(p.path, e, v); }
|
2012-04-10 12:52:06 -05:00
|
|
|
visit_class_ctor_helper(ctor, i.ident, tps,
|
|
|
|
ast_util::local_def(i.id), e, v);
|
2012-05-14 16:13:32 -05:00
|
|
|
option::iter(m_dtor) {|dtor|
|
|
|
|
visit_class_dtor_helper(dtor, tps,
|
|
|
|
ast_util::local_def(i.id), e, v)};
|
2012-01-31 21:30:40 -06:00
|
|
|
}
|
2012-04-24 17:52:52 -05:00
|
|
|
item_iface(tps, _rp, methods) {
|
2012-01-04 09:37:39 -06:00
|
|
|
v.visit_ty_params(tps, e, v);
|
2012-04-06 13:01:43 -05:00
|
|
|
for methods.each {|m|
|
|
|
|
for m.decl.inputs.each {|a| v.visit_ty(a.ty, e, v); }
|
2012-05-29 18:49:40 -05:00
|
|
|
v.visit_ty_params(m.tps, e, v);
|
2011-12-20 09:33:55 -06:00
|
|
|
v.visit_ty(m.decl.output, e, v);
|
|
|
|
}
|
|
|
|
}
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-28 20:50:33 -05:00
|
|
|
fn visit_class_item<E>(cm: @class_member, e:E, v:vt<E>) {
|
|
|
|
alt cm.node {
|
|
|
|
instance_var(_, t, _, _, _) {
|
2012-01-31 21:30:40 -06:00
|
|
|
v.visit_ty(t, e, v);
|
|
|
|
}
|
2012-03-19 12:19:00 -05:00
|
|
|
class_method(m) {
|
|
|
|
visit_method_helper(m, e, v);
|
2012-01-31 21:30:40 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-22 03:57:47 -06:00
|
|
|
fn skip_ty<E>(_t: @ty, _e: E, _v: vt<E>) {}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_ty<E>(t: @ty, e: E, v: vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt t.node {
|
2012-04-09 19:32:49 -05:00
|
|
|
ty_box(mt) | ty_uniq(mt) |
|
|
|
|
ty_vec(mt) | ty_ptr(mt) | ty_rptr(_, mt) {
|
|
|
|
v.visit_ty(mt.ty, e, v);
|
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
ty_rec(flds) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for flds.each {|f| v.visit_ty(f.node.mt.ty, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-04-06 13:01:43 -05:00
|
|
|
ty_tup(ts) { for ts.each {|tt| v.visit_ty(tt, e, v); } }
|
2011-12-29 22:07:55 -06:00
|
|
|
ty_fn(_, decl) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for decl.inputs.each {|a| v.visit_ty(a.ty, e, v); }
|
|
|
|
for decl.constraints.each {|c|
|
2011-07-27 07:19:39 -05:00
|
|
|
v.visit_constr(c.node.path, c.span, c.node.id, e, v);
|
|
|
|
}
|
2011-12-22 10:49:54 -06:00
|
|
|
v.visit_ty(decl.output, e, v);
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2011-12-13 06:19:56 -06:00
|
|
|
ty_path(p, _) { visit_path(p, e, v); }
|
2012-04-09 19:32:49 -05:00
|
|
|
ty_vstore(t, _) {
|
|
|
|
v.visit_ty(t, e, v);
|
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
ty_constr(t, cs) {
|
|
|
|
v.visit_ty(t, e, v);
|
2012-04-06 13:01:43 -05:00
|
|
|
for cs.each {|tc|
|
2011-07-27 07:19:39 -05:00
|
|
|
v.visit_constr(tc.node.path, tc.span, tc.node.id, e, v);
|
|
|
|
}
|
|
|
|
}
|
2012-03-28 14:54:06 -05:00
|
|
|
ty_nil |
|
|
|
|
ty_bot |
|
|
|
|
ty_mac(_) |
|
|
|
|
ty_infer {
|
|
|
|
}
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-30 06:38:38 -06:00
|
|
|
fn visit_constr<E>(_operator: @path, _sp: span, _id: node_id, _e: E,
|
2011-09-12 04:27:30 -05:00
|
|
|
_v: vt<E>) {
|
2011-06-10 21:12:42 -05:00
|
|
|
// default
|
|
|
|
}
|
|
|
|
|
2011-12-13 06:19:56 -06:00
|
|
|
fn visit_path<E>(p: @path, e: E, v: vt<E>) {
|
2012-04-23 06:04:46 -05:00
|
|
|
for p.types.each {|tp| v.visit_ty(tp, e, v); }
|
2011-12-13 06:19:56 -06:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_pat<E>(p: @pat, e: E, v: vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt p.node {
|
2012-01-25 07:34:31 -06:00
|
|
|
pat_enum(path, children) {
|
2011-12-13 06:19:56 -06:00
|
|
|
visit_path(path, e, v);
|
2012-04-20 02:54:42 -05:00
|
|
|
option::iter(children) {|children|
|
|
|
|
for children.each {|child| v.visit_pat(child, e, v); }}
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
pat_rec(fields, _) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for fields.each {|f| v.visit_pat(f.pat, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-04-06 13:01:43 -05:00
|
|
|
pat_tup(elts) { for elts.each {|elt| v.visit_pat(elt, e, v); } }
|
2012-01-14 18:05:07 -06:00
|
|
|
pat_box(inner) | pat_uniq(inner) {
|
2011-12-08 04:56:16 -06:00
|
|
|
v.visit_pat(inner, e, v);
|
|
|
|
}
|
2012-01-14 18:05:07 -06:00
|
|
|
pat_ident(path, inner) {
|
|
|
|
visit_path(path, e, v);
|
2012-04-20 02:54:42 -05:00
|
|
|
option::iter(inner) {|subpat| v.visit_pat(subpat, e, v)};
|
2012-01-14 18:05:07 -06:00
|
|
|
}
|
2012-03-14 11:24:47 -05:00
|
|
|
pat_lit(ex) { v.visit_expr(ex, e, v); }
|
|
|
|
pat_range(e1, e2) { v.visit_expr(e1, e, v); v.visit_expr(e2, e, v); }
|
|
|
|
pat_wild {}
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_native_item<E>(ni: @native_item, e: E, v: vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt ni.node {
|
2011-12-28 10:50:12 -06:00
|
|
|
native_item_fn(fd, tps) {
|
2012-01-04 09:37:39 -06:00
|
|
|
v.visit_ty_params(tps, e, v);
|
2011-12-28 10:50:12 -06:00
|
|
|
visit_fn_decl(fd, e, v);
|
|
|
|
}
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-28 10:50:12 -06:00
|
|
|
fn visit_ty_params<E>(tps: [ty_param], e: E, v: vt<E>) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for tps.each {|tp|
|
|
|
|
for vec::each(*tp.bounds) {|bound|
|
2011-12-28 10:50:12 -06:00
|
|
|
alt bound {
|
|
|
|
bound_iface(t) { v.visit_ty(t, e, v); }
|
2012-05-24 12:23:46 -05:00
|
|
|
bound_copy | bound_send | bound_const { }
|
2011-12-28 10:50:12 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_fn_decl<E>(fd: fn_decl, e: E, v: vt<E>) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for fd.inputs.each {|a| v.visit_ty(a.ty, e, v); }
|
|
|
|
for fd.constraints.each {|c|
|
2011-07-19 19:52:34 -05:00
|
|
|
v.visit_constr(c.node.path, c.span, c.node.id, e, v);
|
|
|
|
}
|
2011-07-01 07:05:54 -05:00
|
|
|
v.visit_ty(fd.output, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2012-03-01 12:36:22 -06:00
|
|
|
// Note: there is no visit_method() method in the visitor, instead override
|
|
|
|
// visit_fn() and check for fk_method(). I named this visit_method_helper()
|
|
|
|
// because it is not a default impl of any method, though I doubt that really
|
|
|
|
// clarifies anything. - Niko
|
|
|
|
fn visit_method_helper<E>(m: @method, e: E, v: vt<E>) {
|
2012-06-21 18:44:10 -05:00
|
|
|
v.visit_fn(fk_method(/* FIXME (#2543) */ copy m.ident,
|
|
|
|
/* FIXME (#2543) */ copy m.tps, m),
|
2012-06-07 23:53:47 -05:00
|
|
|
m.decl, m.body, m.span, m.id, e, v);
|
2012-03-01 12:36:22 -06:00
|
|
|
}
|
|
|
|
|
2012-04-10 12:52:06 -05:00
|
|
|
// Similar logic to the comment on visit_method_helper - Tim
|
|
|
|
fn visit_class_ctor_helper<E>(ctor: class_ctor, nm: ident, tps: [ty_param],
|
|
|
|
parent_id: def_id, e: E, v: vt<E>) {
|
2012-06-21 18:44:10 -05:00
|
|
|
v.visit_fn(fk_ctor(/* FIXME (#2543) */ copy nm,
|
|
|
|
/* FIXME (#2543) */ copy tps,
|
2012-06-07 23:53:47 -05:00
|
|
|
ctor.node.self_id, parent_id), ctor.node.dec,
|
2012-04-10 12:52:06 -05:00
|
|
|
ctor.node.body, ctor.span, ctor.node.id, e, v)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-05-14 16:13:32 -05:00
|
|
|
fn visit_class_dtor_helper<E>(dtor: class_dtor, tps: [ty_param],
|
|
|
|
parent_id: def_id, e: E, v: vt<E>) {
|
2012-06-21 18:44:10 -05:00
|
|
|
v.visit_fn(fk_dtor(/* FIXME (#2543) */ copy tps, dtor.node.self_id,
|
2012-05-14 16:13:32 -05:00
|
|
|
parent_id), ast_util::dtor_dec(),
|
|
|
|
dtor.node.body, dtor.span, dtor.node.id, e, v)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-12-29 22:07:55 -06:00
|
|
|
fn visit_fn<E>(fk: fn_kind, decl: fn_decl, body: blk, _sp: span,
|
|
|
|
_id: node_id, e: E, v: vt<E>) {
|
2011-12-20 13:03:21 -06:00
|
|
|
visit_fn_decl(decl, e, v);
|
2012-01-04 09:37:39 -06:00
|
|
|
v.visit_ty_params(tps_of_fn(fk), e, v);
|
2011-12-20 13:03:21 -06:00
|
|
|
v.visit_block(body, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_block<E>(b: ast::blk, e: E, v: vt<E>) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for b.node.view_items.each {|vi| v.visit_view_item(vi, e, v); }
|
|
|
|
for b.node.stmts.each {|s| v.visit_stmt(s, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
visit_expr_opt(b.node.expr, e, v);
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_stmt<E>(s: @stmt, e: E, v: vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt s.node {
|
|
|
|
stmt_decl(d, _) { v.visit_decl(d, e, v); }
|
|
|
|
stmt_expr(ex, _) { v.visit_expr(ex, e, v); }
|
2012-01-04 16:16:41 -06:00
|
|
|
stmt_semi(ex, _) { v.visit_expr(ex, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_decl<E>(d: @decl, e: E, v: vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt d.node {
|
|
|
|
decl_local(locs) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for locs.each {|loc| v.visit_local(loc, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
decl_item(it) { v.visit_item(it, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-31 19:05:20 -06:00
|
|
|
fn visit_expr_opt<E>(eo: option<@expr>, e: E, v: vt<E>) {
|
2012-01-19 00:37:22 -06:00
|
|
|
alt eo { none { } some(ex) { v.visit_expr(ex, e, v); } }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_exprs<E>(exprs: [@expr], e: E, v: vt<E>) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for exprs.each {|ex| v.visit_expr(ex, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_mac<E>(m: mac, e: E, v: vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt m.node {
|
2012-02-01 01:20:31 -06:00
|
|
|
ast::mac_invoc(pth, arg, body) {
|
2012-03-12 10:31:22 -05:00
|
|
|
option::map(arg) {|arg| v.visit_expr(arg, e, v)}; }
|
2012-05-21 12:45:56 -05:00
|
|
|
ast::mac_invoc_tt(pth, tt) { /* no user-serviceable parts inside */ }
|
2011-07-27 07:19:39 -05:00
|
|
|
ast::mac_embed_type(ty) { v.visit_ty(ty, e, v); }
|
|
|
|
ast::mac_embed_block(blk) { v.visit_block(blk, e, v); }
|
2012-01-19 00:37:22 -06:00
|
|
|
ast::mac_ellipsis { }
|
2012-05-03 15:04:40 -05:00
|
|
|
ast::mac_aq(_, e) { /* FIXME: maybe visit (Issue #2340) */ }
|
2012-01-25 17:38:09 -06:00
|
|
|
ast::mac_var(_) { }
|
2011-07-08 18:35:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt ex.node {
|
2012-03-14 14:16:46 -05:00
|
|
|
expr_new(pool, _, val) {
|
|
|
|
v.visit_expr(pool, e, v);
|
|
|
|
v.visit_expr(val, e, v);
|
|
|
|
}
|
2012-04-09 19:32:49 -05:00
|
|
|
expr_vstore(x, _) { v.visit_expr(x, e, v); }
|
2011-08-18 13:37:19 -05:00
|
|
|
expr_vec(es, _) { visit_exprs(es, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_rec(flds, base) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for flds.each {|f| v.visit_expr(f.node.expr, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
visit_expr_opt(base, e, v);
|
|
|
|
}
|
2012-04-06 13:01:43 -05:00
|
|
|
expr_tup(elts) { for elts.each {|el| v.visit_expr(el, e, v); } }
|
2011-10-21 07:11:24 -05:00
|
|
|
expr_call(callee, args, _) {
|
2011-07-27 07:19:39 -05:00
|
|
|
visit_exprs(args, e, v);
|
2011-08-30 10:03:00 -05:00
|
|
|
v.visit_expr(callee, e, v);
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
expr_binary(_, a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); }
|
2012-06-18 19:42:09 -05:00
|
|
|
expr_addr_of(_, x) | expr_unary(_, x) |
|
|
|
|
expr_loop_body(x) | expr_do_body(x) |
|
2012-03-26 09:09:27 -05:00
|
|
|
expr_check(_, x) | expr_assert(x) {
|
|
|
|
v.visit_expr(x, e, v);
|
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_lit(_) { }
|
|
|
|
expr_cast(x, t) { v.visit_expr(x, e, v); v.visit_ty(t, e, v); }
|
|
|
|
expr_if(x, b, eo) {
|
|
|
|
v.visit_expr(x, e, v);
|
|
|
|
v.visit_block(b, e, v);
|
|
|
|
visit_expr_opt(eo, e, v);
|
|
|
|
}
|
|
|
|
expr_if_check(x, b, eo) {
|
|
|
|
v.visit_expr(x, e, v);
|
|
|
|
v.visit_block(b, e, v);
|
|
|
|
visit_expr_opt(eo, e, v);
|
|
|
|
}
|
|
|
|
expr_while(x, b) { v.visit_expr(x, e, v); v.visit_block(b, e, v); }
|
2012-03-26 09:09:27 -05:00
|
|
|
expr_loop(b) { v.visit_block(b, e, v); }
|
2012-02-15 02:35:11 -06:00
|
|
|
expr_alt(x, arms, _) {
|
2011-07-27 07:19:39 -05:00
|
|
|
v.visit_expr(x, e, v);
|
2012-04-06 13:01:43 -05:00
|
|
|
for arms.each {|a| v.visit_arm(a, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-05-07 13:31:57 -05:00
|
|
|
expr_fn(proto, decl, body, cap_clause) {
|
|
|
|
v.visit_fn(fk_anon(proto, cap_clause), decl, body,
|
|
|
|
ex.span, ex.id, e, v);
|
2011-12-20 13:03:21 -06:00
|
|
|
}
|
2012-05-07 13:31:57 -05:00
|
|
|
expr_fn_block(decl, body, cap_clause) {
|
|
|
|
v.visit_fn(fk_fn_block(cap_clause), decl, body,
|
|
|
|
ex.span, ex.id, e, v);
|
2011-12-20 13:03:21 -06:00
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_block(b) { v.visit_block(b, e, v); }
|
|
|
|
expr_assign(a, b) { v.visit_expr(b, e, v); v.visit_expr(a, e, v); }
|
2011-08-15 17:35:40 -05:00
|
|
|
expr_copy(a) { v.visit_expr(a, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_move(a, b) { v.visit_expr(b, e, v); v.visit_expr(a, e, v); }
|
|
|
|
expr_swap(a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); }
|
|
|
|
expr_assign_op(_, a, b) {
|
|
|
|
v.visit_expr(b, e, v);
|
|
|
|
v.visit_expr(a, e, v);
|
|
|
|
}
|
2011-12-19 03:21:31 -06:00
|
|
|
expr_field(x, _, tys) {
|
|
|
|
v.visit_expr(x, e, v);
|
2012-04-06 13:01:43 -05:00
|
|
|
for tys.each {|tp| v.visit_ty(tp, e, v); }
|
2011-12-19 03:21:31 -06:00
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_index(a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); }
|
2011-12-13 06:19:56 -06:00
|
|
|
expr_path(p) { visit_path(p, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_fail(eo) { visit_expr_opt(eo, e, v); }
|
2012-01-19 00:37:22 -06:00
|
|
|
expr_break { }
|
|
|
|
expr_cont { }
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_ret(eo) { visit_expr_opt(eo, e, v); }
|
2011-12-21 16:31:31 -06:00
|
|
|
expr_log(_, lv, x) {
|
|
|
|
v.visit_expr(lv, e, v);
|
|
|
|
v.visit_expr(x, e, v);
|
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_mac(mac) { visit_mac(mac, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn visit_arm<E>(a: arm, e: E, v: vt<E>) {
|
2012-04-06 13:01:43 -05:00
|
|
|
for a.pats.each {|p| v.visit_pat(p, e, v); }
|
2011-08-22 07:38:48 -05:00
|
|
|
visit_expr_opt(a.guard, e, v);
|
2011-08-10 17:38:41 -05:00
|
|
|
v.visit_block(a.body, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
2011-07-01 07:05:54 -05:00
|
|
|
|
2011-07-26 09:35:31 -05:00
|
|
|
// Simpler, non-context passing interface. Always walks the whole tree, simply
|
|
|
|
// calls the given functions on the nodes.
|
|
|
|
|
|
|
|
type simple_visitor =
|
2011-07-27 07:19:39 -05:00
|
|
|
// takes the components so that one function can be
|
|
|
|
// generic over constr and ty_constr
|
2012-01-26 10:33:12 -06:00
|
|
|
@{visit_mod: fn@(_mod, span, node_id),
|
2011-10-18 17:07:40 -05:00
|
|
|
visit_view_item: fn@(@view_item),
|
|
|
|
visit_native_item: fn@(@native_item),
|
|
|
|
visit_item: fn@(@item),
|
|
|
|
visit_local: fn@(@local),
|
|
|
|
visit_block: fn@(ast::blk),
|
|
|
|
visit_stmt: fn@(@stmt),
|
|
|
|
visit_arm: fn@(arm),
|
|
|
|
visit_pat: fn@(@pat),
|
|
|
|
visit_decl: fn@(@decl),
|
|
|
|
visit_expr: fn@(@expr),
|
|
|
|
visit_ty: fn@(@ty),
|
2012-01-04 09:37:39 -06:00
|
|
|
visit_ty_params: fn@([ty_param]),
|
2011-11-30 06:38:38 -06:00
|
|
|
visit_constr: fn@(@path, span, node_id),
|
2012-01-31 21:30:40 -06:00
|
|
|
visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id),
|
2012-03-28 20:50:33 -05:00
|
|
|
visit_class_item: fn@(@class_member)};
|
2011-07-26 09:35:31 -05:00
|
|
|
|
2011-11-22 03:57:47 -06:00
|
|
|
fn simple_ignore_ty(_t: @ty) {}
|
|
|
|
|
2011-07-26 09:35:31 -05:00
|
|
|
fn default_simple_visitor() -> simple_visitor {
|
2012-01-26 10:33:12 -06:00
|
|
|
ret @{visit_mod: fn@(_m: _mod, _sp: span, _id: node_id) { },
|
2012-01-11 11:58:05 -06:00
|
|
|
visit_view_item: fn@(_vi: @view_item) { },
|
|
|
|
visit_native_item: fn@(_ni: @native_item) { },
|
|
|
|
visit_item: fn@(_i: @item) { },
|
|
|
|
visit_local: fn@(_l: @local) { },
|
|
|
|
visit_block: fn@(_b: ast::blk) { },
|
|
|
|
visit_stmt: fn@(_s: @stmt) { },
|
|
|
|
visit_arm: fn@(_a: arm) { },
|
|
|
|
visit_pat: fn@(_p: @pat) { },
|
|
|
|
visit_decl: fn@(_d: @decl) { },
|
|
|
|
visit_expr: fn@(_e: @expr) { },
|
2011-11-22 03:57:47 -06:00
|
|
|
visit_ty: simple_ignore_ty,
|
2012-01-11 11:58:05 -06:00
|
|
|
visit_ty_params: fn@(_ps: [ty_param]) {},
|
|
|
|
visit_constr: fn@(_p: @path, _sp: span, _id: node_id) { },
|
|
|
|
visit_fn: fn@(_fk: fn_kind, _d: fn_decl, _b: blk, _sp: span,
|
2012-01-31 21:30:40 -06:00
|
|
|
_id: node_id) { },
|
2012-03-28 20:50:33 -05:00
|
|
|
visit_class_item: fn@(_c: @class_member) {}
|
2011-12-20 13:03:21 -06:00
|
|
|
};
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
|
|
|
|
2011-09-12 04:27:30 -05:00
|
|
|
fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
|
2012-01-26 10:33:12 -06:00
|
|
|
fn v_mod(f: fn@(_mod, span, node_id), m: _mod, sp: span, id: node_id,
|
|
|
|
&&e: (), v: vt<()>) {
|
|
|
|
f(m, sp, id);
|
|
|
|
visit_mod(m, sp, id, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -05:00
|
|
|
fn v_view_item(f: fn@(@view_item), vi: @view_item, &&e: (), v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(vi);
|
|
|
|
visit_view_item(vi, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -05:00
|
|
|
fn v_native_item(f: fn@(@native_item), ni: @native_item, &&e: (),
|
2011-09-12 04:27:30 -05:00
|
|
|
v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(ni);
|
|
|
|
visit_native_item(ni, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -05:00
|
|
|
fn v_item(f: fn@(@item), i: @item, &&e: (), v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(i);
|
|
|
|
visit_item(i, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -05:00
|
|
|
fn v_local(f: fn@(@local), l: @local, &&e: (), v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(l);
|
|
|
|
visit_local(l, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -05:00
|
|
|
fn v_block(f: fn@(ast::blk), bl: ast::blk, &&e: (), v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(bl);
|
|
|
|
visit_block(bl, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -05:00
|
|
|
fn v_stmt(f: fn@(@stmt), st: @stmt, &&e: (), v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(st);
|
|
|
|
visit_stmt(st, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -05:00
|
|
|
fn v_arm(f: fn@(arm), a: arm, &&e: (), v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(a);
|
|
|
|
visit_arm(a, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -05:00
|
|
|
fn v_pat(f: fn@(@pat), p: @pat, &&e: (), v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(p);
|
|
|
|
visit_pat(p, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -05:00
|
|
|
fn v_decl(f: fn@(@decl), d: @decl, &&e: (), v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(d);
|
|
|
|
visit_decl(d, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -05:00
|
|
|
fn v_expr(f: fn@(@expr), ex: @expr, &&e: (), v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(ex);
|
|
|
|
visit_expr(ex, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -05:00
|
|
|
fn v_ty(f: fn@(@ty), ty: @ty, &&e: (), v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(ty);
|
|
|
|
visit_ty(ty, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2012-01-04 09:37:39 -06:00
|
|
|
fn v_ty_params(f: fn@([ty_param]), ps: [ty_param], &&e: (), v: vt<()>) {
|
|
|
|
f(ps);
|
|
|
|
visit_ty_params(ps, e, v);
|
|
|
|
}
|
2011-11-30 06:38:38 -06:00
|
|
|
fn v_constr(f: fn@(@path, span, node_id), pt: @path, sp: span,
|
|
|
|
id: node_id, &&e: (), v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(pt, sp, id);
|
|
|
|
visit_constr(pt, sp, id, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-12-29 22:07:55 -06:00
|
|
|
fn v_fn(f: fn@(fn_kind, fn_decl, blk, span, node_id),
|
|
|
|
fk: fn_kind, decl: fn_decl, body: blk, sp: span,
|
|
|
|
id: node_id, &&e: (), v: vt<()>) {
|
|
|
|
f(fk, decl, body, sp, id);
|
|
|
|
visit_fn(fk, decl, body, sp, id, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-11-22 03:57:47 -06:00
|
|
|
let visit_ty = if v.visit_ty == simple_ignore_ty {
|
2012-06-19 21:34:01 -05:00
|
|
|
{|a,b,c| skip_ty(a, b, c)}
|
2011-11-22 03:57:47 -06:00
|
|
|
} else {
|
2012-06-19 21:34:01 -05:00
|
|
|
{|a,b,c| v_ty(v.visit_ty, a, b, c)}
|
2011-11-22 03:57:47 -06:00
|
|
|
};
|
2012-03-28 20:50:33 -05:00
|
|
|
fn v_class_item(f: fn@(@class_member),
|
|
|
|
cm: @class_member, &&e: (),
|
2012-01-31 21:30:40 -06:00
|
|
|
v: vt<()>) {
|
2012-03-28 20:50:33 -05:00
|
|
|
f(cm);
|
|
|
|
visit_class_item(cm, e, v);
|
2012-01-31 21:30:40 -06:00
|
|
|
}
|
2012-06-19 21:34:01 -05:00
|
|
|
ret mk_vt(@{visit_mod: {|a,b,c,d,e|v_mod(v.visit_mod, a, b, c, d, e)},
|
|
|
|
visit_view_item: {|a,b,c|
|
|
|
|
v_view_item(v.visit_view_item, a, b, c)
|
|
|
|
},
|
2011-07-27 07:19:39 -05:00
|
|
|
visit_native_item:
|
2012-06-19 21:34:01 -05:00
|
|
|
{|a,b,c|v_native_item(v.visit_native_item, a, b, c)},
|
|
|
|
visit_item: {|a,b,c|v_item(v.visit_item, a, b, c)},
|
|
|
|
visit_local: {|a,b,c|v_local(v.visit_local, a, b, c)},
|
|
|
|
visit_block: {|a,b,c|v_block(v.visit_block, a, b, c)},
|
|
|
|
visit_stmt: {|a,b,c|v_stmt(v.visit_stmt, a, b, c)},
|
|
|
|
visit_arm: {|a,b,c|v_arm(v.visit_arm, a, b, c)},
|
|
|
|
visit_pat: {|a,b,c|v_pat(v.visit_pat, a, b, c)},
|
|
|
|
visit_decl: {|a,b,c|v_decl(v.visit_decl, a, b, c)},
|
|
|
|
visit_expr: {|a,b,c|v_expr(v.visit_expr, a, b, c)},
|
2011-11-22 03:57:47 -06:00
|
|
|
visit_ty: visit_ty,
|
2012-06-19 21:34:01 -05:00
|
|
|
visit_ty_params: {|a,b,c|
|
|
|
|
v_ty_params(v.visit_ty_params, a, b, c)
|
|
|
|
},
|
|
|
|
visit_constr: {|a,b,c,d,e|
|
|
|
|
v_constr(v.visit_constr, a, b, c, d, e)
|
|
|
|
},
|
|
|
|
visit_fn: {|a,b,c,d,e,f,g|
|
|
|
|
v_fn(v.visit_fn, a, b, c, d, e, f, g)
|
|
|
|
},
|
|
|
|
visit_class_item: {|a,b,c|
|
|
|
|
v_class_item(v.visit_class_item, a, b, c)
|
|
|
|
}
|
2011-12-20 13:03:21 -06:00
|
|
|
});
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
|
|
|
|
2011-06-08 15:48:19 -05:00
|
|
|
// Local Variables:
|
|
|
|
// mode: rust
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
|
|
|
// End:
|