Allow ast_fold_precursor to change the span.

This involved changing the prototype for the callbacks to thread the
span though.  A wrapper function, fold::wrap, can be used to wrap the
old style callbacks.
This commit is contained in:
Kevin Atkinson 2012-01-22 17:30:07 -07:00 committed by Brian Anderson
parent ad21d9c64a
commit 20ab47fe49
6 changed files with 113 additions and 83 deletions

View File

@ -27,7 +27,7 @@ fn strip_items(crate: @ast::crate, in_cfg: in_cfg_pred)
let precursor =
{fold_mod: bind fold_mod(ctxt, _, _),
fold_block: bind fold_block(ctxt, _, _),
fold_block: fold::wrap(bind fold_block(ctxt, _, _)),
fold_native_mod: bind fold_native_mod(ctxt, _, _)
with *fold::default_ast_fold()};

View File

@ -44,7 +44,7 @@ fn generate_test_harness(sess: session::session,
mutable testfns: []};
let precursor =
{fold_crate: bind fold_crate(cx, _, _),
{fold_crate: fold::wrap(bind fold_crate(cx, _, _)),
fold_item: bind fold_item(cx, _, _),
fold_mod: bind fold_mod(cx, _, _) with *fold::default_ast_fold()};

View File

@ -10,8 +10,13 @@ import syntax::fold::*;
import syntax::ext::base::*;
import syntax::parse::parser::parse_expr_from_source_str;
fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, e: expr_,
fld: ast_fold, orig: fn@(expr_, ast_fold) -> expr_) -> expr_ {
import codemap::span;
fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt,
e: expr_, s: span, fld: ast_fold,
orig: fn@(expr_, span, ast_fold) -> (expr_, span))
-> (expr_, span)
{
ret alt e {
expr_mac(mac) {
alt mac.node {
@ -31,19 +36,19 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, e: expr_,
let fully_expanded = fld.fold_expr(expanded).node;
cx.bt_pop();
fully_expanded
(fully_expanded, s)
}
some(macro_defining(ext)) {
let named_extension = ext(cx, pth.span, args, body);
exts.insert(named_extension.ident, named_extension.ext);
ast::expr_rec([], none)
(ast::expr_rec([], none), s)
}
}
}
_ { cx.span_bug(mac.span, "naked syntactic bit") }
}
}
_ { orig(e, fld) }
_ { orig(e, s, fld) }
};
}
@ -67,7 +72,7 @@ fn expand_crate(sess: session::session, c: @crate) -> @crate {
let afp = default_ast_fold();
let cx: ext_ctxt = mk_ctxt(sess);
let f_pre =
{fold_expr: bind expand_expr(exts, cx, _, _, afp.fold_expr)
{fold_expr: bind expand_expr(exts, cx, _, _, _, afp.fold_expr)
with *afp};
let f = make_fold(f_pre);
let cm = parse_expr_from_source_str("<anon>", core_macros(),

View File

@ -194,12 +194,12 @@ fn transcribe(cx: ext_ctxt, b: bindings, body: @expr) -> @expr {
let afp = default_ast_fold();
let f_pre =
{fold_ident: bind transcribe_ident(cx, b, idx_path, _, _),
fold_path: bind transcribe_path(cx, b, idx_path, _, _),
fold_path: bind transcribe_path(cx, b, idx_path, _, _, _),
fold_expr:
bind transcribe_expr(cx, b, idx_path, _, _, afp.fold_expr),
fold_ty: bind transcribe_type(cx, b, idx_path, _, _, afp.fold_ty),
bind transcribe_expr(cx, b, idx_path, _, _, _, afp.fold_expr),
fold_ty: bind transcribe_type(cx, b, idx_path, _, _, _, afp.fold_ty),
fold_block:
bind transcribe_block(cx, b, idx_path, _, _, afp.fold_block),
bind transcribe_block(cx, b, idx_path, _, _, _, afp.fold_block),
map_exprs: bind transcribe_exprs(cx, b, idx_path, _, _),
new_id: bind new_id(_, cx),
new_span: bind new_span(cx, _) with *afp};
@ -209,7 +209,6 @@ fn transcribe(cx: ext_ctxt, b: bindings, body: @expr) -> @expr {
}
/* helper: descend into a matcher */
fn follow(m: arb_depth<matchable>, idx_path: @mutable [uint]) ->
arb_depth<matchable> {
@ -334,64 +333,67 @@ fn transcribe_ident(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
fn transcribe_path(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
p: path_, _fld: ast_fold) -> path_ {
p: path_, s:span, _fld: ast_fold) -> (path_, span) {
// Don't substitute into qualified names.
if vec::len(p.types) > 0u || vec::len(p.idents) != 1u { ret p; }
if vec::len(p.types) > 0u || vec::len(p.idents) != 1u { ret (p, s); }
ret alt follow_for_trans(cx, b.find(p.idents[0]), idx_path) {
some(match_ident(id)) {
{global: false, idents: [id.node], types: []}
({global: false, idents: [id.node], types: []}, s)
}
some(match_path(a_pth)) { a_pth.node }
some(match_path(a_pth)) { (a_pth.node, s) }
some(m) { match_error(cx, m, "a path") }
none { p }
none { (p, s) }
}
}
fn transcribe_expr(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
e: ast::expr_, fld: ast_fold,
orig: fn@(ast::expr_, ast_fold) -> ast::expr_) ->
ast::expr_ {
e: ast::expr_, s: span, fld: ast_fold,
orig: fn@(ast::expr_, span, ast_fold)->(ast::expr_, span))
-> (ast::expr_, span)
{
ret alt e {
expr_path(p) {
// Don't substitute into qualified names.
if vec::len(p.node.types) > 0u || vec::len(p.node.idents) != 1u {
e;
(e, s);
}
alt follow_for_trans(cx, b.find(p.node.idents[0]), idx_path) {
some(match_ident(id)) {
expr_path(@respan(id.span,
{global: false,
idents: [id.node],
types: []}))
(expr_path(@respan(id.span,
{global: false,
idents: [id.node],
types: []})), s)
}
some(match_path(a_pth)) { expr_path(a_pth) }
some(match_expr(a_exp)) { a_exp.node }
some(match_path(a_pth)) { (expr_path(a_pth), s) }
some(match_expr(a_exp)) { (a_exp.node, s) }
some(m) { match_error(cx, m, "an expression") }
none { orig(e, fld) }
none { orig(e, s, fld) }
}
}
_ { orig(e, fld) }
_ { orig(e, s, fld) }
}
}
fn transcribe_type(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
t: ast::ty_, fld: ast_fold,
orig: fn@(ast::ty_, ast_fold) -> ast::ty_) -> ast::ty_ {
t: ast::ty_, s: span, fld: ast_fold,
orig: fn@(ast::ty_, span, ast_fold) -> (ast::ty_, span))
-> (ast::ty_, span)
{
ret alt t {
ast::ty_path(pth, _) {
alt path_to_ident(pth) {
some(id) {
alt follow_for_trans(cx, b.find(id), idx_path) {
some(match_ty(ty)) { ty.node }
some(match_ty(ty)) { (ty.node, s) }
some(m) { match_error(cx, m, "a type") }
none { orig(t, fld) }
none { orig(t, s, fld) }
}
}
none { orig(t, fld) }
none { orig(t, s, fld) }
}
}
_ { orig(t, fld) }
_ { orig(t, s, fld) }
}
}
@ -400,12 +402,14 @@ fn transcribe_type(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
`{v}` */
fn transcribe_block(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
blk: blk_, fld: ast_fold,
orig: fn@(blk_, ast_fold) -> blk_) -> blk_ {
blk: blk_, s: span, fld: ast_fold,
orig: fn@(blk_, span, ast_fold) -> (blk_, span))
-> (blk_, span)
{
ret alt block_to_ident(blk) {
some(id) {
alt follow_for_trans(cx, b.find(id), idx_path) {
some(match_block(new_blk)) { new_blk.node }
some(match_block(new_blk)) { (new_blk.node, s) }
@ -415,10 +419,10 @@ fn transcribe_block(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
some(m) {
match_error(cx, m, "a block")
}
none { orig(blk, fld) }
none { orig(blk, s, fld) }
}
}
none { orig(blk, fld) }
none { orig(blk, s, fld) }
}
}

View File

@ -13,6 +13,7 @@ export noop_fold_expr;
export noop_fold_pat;
export noop_fold_mod;
export noop_fold_ty;
export wrap;
type ast_fold = @mutable a_f;
@ -20,28 +21,28 @@ type ast_fold = @mutable a_f;
type ast_fold_precursor =
//unlike the others, item_ is non-trivial
{fold_crate: fn@(crate_, ast_fold) -> crate_,
fold_crate_directive: fn@(crate_directive_,
ast_fold) -> crate_directive_,
{fold_crate: fn@(crate_, span, ast_fold) -> (crate_, span),
fold_crate_directive: fn@(crate_directive_, span,
ast_fold) -> (crate_directive_, span),
fold_view_item: fn@(view_item_, ast_fold) -> view_item_,
fold_native_item: fn@(&&@native_item, ast_fold) -> @native_item,
fold_item: fn@(&&@item, ast_fold) -> @item,
fold_item_underscore: fn@(item_, ast_fold) -> item_,
fold_method: fn@(&&@method, ast_fold) -> @method,
fold_block: fn@(blk_, ast_fold) -> blk_,
fold_stmt: fn@(stmt_, ast_fold) -> stmt_,
fold_block: fn@(blk_, span, ast_fold) -> (blk_, span),
fold_stmt: fn@(stmt_, span, ast_fold) -> (stmt_, span),
fold_arm: fn@(arm, ast_fold) -> arm,
fold_pat: fn@(pat_, ast_fold) -> pat_,
fold_decl: fn@(decl_, ast_fold) -> decl_,
fold_expr: fn@(expr_, ast_fold) -> expr_,
fold_ty: fn@(ty_, ast_fold) -> ty_,
fold_constr: fn@(ast::constr_, ast_fold) -> constr_,
fold_pat: fn@(pat_, span, ast_fold) -> (pat_, span),
fold_decl: fn@(decl_, span, ast_fold) -> (decl_, span),
fold_expr: fn@(expr_, span, ast_fold) -> (expr_, span),
fold_ty: fn@(ty_, span, ast_fold) -> (ty_, span),
fold_constr: fn@(ast::constr_, span, ast_fold) -> (constr_, span),
fold_mod: fn@(_mod, ast_fold) -> _mod,
fold_native_mod: fn@(native_mod, ast_fold) -> native_mod,
fold_variant: fn@(variant_, ast_fold) -> variant_,
fold_variant: fn@(variant_, span, ast_fold) -> (variant_, span),
fold_ident: fn@(&&ident, ast_fold) -> ident,
fold_path: fn@(path_, ast_fold) -> path_,
fold_local: fn@(local_, ast_fold) -> local_,
fold_path: fn@(path_, span, ast_fold) -> (path_, span),
fold_local: fn@(local_, span, ast_fold) -> (local_, span),
map_exprs: fn@(fn@(&&@expr) -> @expr, [@expr]) -> [@expr],
new_id: fn@(node_id) -> node_id,
new_span: fn@(span) -> span};
@ -305,6 +306,14 @@ fn noop_fold_decl(d: decl_, fld: ast_fold) -> decl_ {
}
}
fn wrap<T>(f: fn@(T, ast_fold) -> T)
-> fn@(T, span, ast_fold) -> (T, span)
{
ret fn@(x: T, s: span, fld: ast_fold) -> (T, span) {
(f(x, fld), s)
}
}
fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
fn fold_field_(field: field, fld: ast_fold) -> field {
ret {node:
@ -474,27 +483,27 @@ fn noop_span(sp: span) -> span { ret sp; }
fn default_ast_fold() -> @ast_fold_precursor {
ret @{fold_crate: noop_fold_crate,
fold_crate_directive: noop_fold_crate_directive,
ret @{fold_crate: wrap(noop_fold_crate),
fold_crate_directive: wrap(noop_fold_crate_directive),
fold_view_item: noop_fold_view_item,
fold_native_item: noop_fold_native_item,
fold_item: noop_fold_item,
fold_item_underscore: noop_fold_item_underscore,
fold_method: noop_fold_method,
fold_block: noop_fold_block,
fold_stmt: noop_fold_stmt,
fold_block: wrap(noop_fold_block),
fold_stmt: wrap(noop_fold_stmt),
fold_arm: noop_fold_arm,
fold_pat: noop_fold_pat,
fold_decl: noop_fold_decl,
fold_expr: noop_fold_expr,
fold_ty: noop_fold_ty,
fold_constr: noop_fold_constr,
fold_pat: wrap(noop_fold_pat),
fold_decl: wrap(noop_fold_decl),
fold_expr: wrap(noop_fold_expr),
fold_ty: wrap(noop_fold_ty),
fold_constr: wrap(noop_fold_constr),
fold_mod: noop_fold_mod,
fold_native_mod: noop_fold_native_mod,
fold_variant: noop_fold_variant,
fold_variant: wrap(noop_fold_variant),
fold_ident: noop_fold_ident,
fold_path: noop_fold_path,
fold_local: noop_fold_local,
fold_path: wrap(noop_fold_path),
fold_local: wrap(noop_fold_local),
map_exprs: noop_map_exprs,
new_id: noop_id,
new_span: noop_span};
@ -531,12 +540,14 @@ fn make_fold(afp: ast_fold_precursor) -> ast_fold {
/* naturally, a macro to write these would be nice */
fn f_crate(afp: ast_fold_precursor, f: ast_fold, c: crate) -> crate {
ret {node: afp.fold_crate(c.node, f), span: afp.new_span(c.span)};
let (n, s) = afp.fold_crate(c.node, c.span, f);
ret {node: n, span: afp.new_span(s)};
}
fn f_crate_directive(afp: ast_fold_precursor, f: ast_fold,
&&c: @crate_directive) -> @crate_directive {
ret @{node: afp.fold_crate_directive(c.node, f),
span: afp.new_span(c.span)};
let (n, s) = afp.fold_crate_directive(c.node, c.span, f);
ret @{node: n,
span: afp.new_span(s)};
}
fn f_view_item(afp: ast_fold_precursor, f: ast_fold, &&x: @view_item) ->
@view_item {
@ -559,33 +570,40 @@ fn make_fold(afp: ast_fold_precursor) -> ast_fold {
ret afp.fold_method(x, f);
}
fn f_block(afp: ast_fold_precursor, f: ast_fold, x: blk) -> blk {
ret {node: afp.fold_block(x.node, f), span: afp.new_span(x.span)};
let (n, s) = afp.fold_block(x.node, x.span, f);
ret {node: n, span: afp.new_span(s)};
}
fn f_stmt(afp: ast_fold_precursor, f: ast_fold, &&x: @stmt) -> @stmt {
ret @{node: afp.fold_stmt(x.node, f), span: afp.new_span(x.span)};
let (n, s) = afp.fold_stmt(x.node, x.span, f);
ret @{node: n, span: afp.new_span(s)};
}
fn f_arm(afp: ast_fold_precursor, f: ast_fold, x: arm) -> arm {
ret afp.fold_arm(x, f);
}
fn f_pat(afp: ast_fold_precursor, f: ast_fold, &&x: @pat) -> @pat {
let (n, s) = afp.fold_pat(x.node, x.span, f);
ret @{id: afp.new_id(x.id),
node: afp.fold_pat(x.node, f),
span: afp.new_span(x.span)};
node: n,
span: afp.new_span(s)};
}
fn f_decl(afp: ast_fold_precursor, f: ast_fold, &&x: @decl) -> @decl {
ret @{node: afp.fold_decl(x.node, f), span: afp.new_span(x.span)};
let (n, s) = afp.fold_decl(x.node, x.span, f);
ret @{node: n, span: afp.new_span(s)};
}
fn f_expr(afp: ast_fold_precursor, f: ast_fold, &&x: @expr) -> @expr {
let (n, s) = afp.fold_expr(x.node, x.span, f);
ret @{id: afp.new_id(x.id),
node: afp.fold_expr(x.node, f),
span: afp.new_span(x.span)};
node: n,
span: afp.new_span(s)};
}
fn f_ty(afp: ast_fold_precursor, f: ast_fold, &&x: @ty) -> @ty {
ret @{node: afp.fold_ty(x.node, f), span: afp.new_span(x.span)};
let (n, s) = afp.fold_ty(x.node, x.span, f);
ret @{node: n, span: afp.new_span(s)};
}
fn f_constr(afp: ast_fold_precursor, f: ast_fold, &&x: @ast::constr) ->
@ast::constr {
ret @{node: afp.fold_constr(x.node, f), span: afp.new_span(x.span)};
let (n, s) = afp.fold_constr(x.node, x.span, f);
ret @{node: n, span: afp.new_span(s)};
}
fn f_mod(afp: ast_fold_precursor, f: ast_fold, x: _mod) -> _mod {
ret afp.fold_mod(x, f);
@ -596,16 +614,19 @@ fn make_fold(afp: ast_fold_precursor) -> ast_fold {
}
fn f_variant(afp: ast_fold_precursor, f: ast_fold, x: variant) ->
variant {
ret {node: afp.fold_variant(x.node, f), span: afp.new_span(x.span)};
let (n, s) = afp.fold_variant(x.node, x.span, f);
ret {node: n, span: afp.new_span(s)};
}
fn f_ident(afp: ast_fold_precursor, f: ast_fold, &&x: ident) -> ident {
ret afp.fold_ident(x, f);
}
fn f_path(afp: ast_fold_precursor, f: ast_fold, &&x: @path) -> @path {
ret @{node: afp.fold_path(x.node, f), span: afp.new_span(x.span)};
let (n, s) = afp.fold_path(x.node, x.span, f);
ret @{node: n, span: afp.new_span(s)};
}
fn f_local(afp: ast_fold_precursor, f: ast_fold, &&x: @local) -> @local {
ret @{node: afp.fold_local(x.node, f), span: afp.new_span(x.span)};
let (n, s) = afp.fold_local(x.node, x.span, f);
ret @{node: n, span: afp.new_span(s)};
}
*result =

View File

@ -187,7 +187,7 @@ fn replace_expr_in_crate(crate: ast::crate, i: uint, newexpr: ast::expr, tm: tes
}
}
let afp =
{fold_expr: bind fold_expr_rep(j, i, newexpr.node, _, _, tm)
{fold_expr: fold::wrap(bind fold_expr_rep(j, i, newexpr.node, _, _, tm))
with *fold::default_ast_fold()};
let af = fold::make_fold(afp);
let crate2: @ast::crate = @af.fold_crate(crate);
@ -208,7 +208,7 @@ fn replace_ty_in_crate(crate: ast::crate, i: uint, newty: ast::ty, tm: test_mode
} else { fold::noop_fold_ty(original, fld) }
}
let afp =
{fold_ty: bind fold_ty_rep(j, i, newty.node, _, _, tm)
{fold_ty: fold::wrap(bind fold_ty_rep(j, i, newty.node, _, _, tm))
with *fold::default_ast_fold()};
let af = fold::make_fold(afp);
let crate2: @ast::crate = @af.fold_crate(crate);