diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2012-03-02 14:36:22 -0800 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2012-03-13 21:30:06 -0400 |
| commit | bdd0c9387bb10e0db01c00dcd47ea3e6bc343e45 (patch) | |
| tree | 1dbc43e5cd08037aa6cd11de8e1528b2a118b7f3 /src/rustc/syntax | |
| parent | c3516f091bbf051f8f9d40ea0dda9ab8c4584e74 (diff) | |
| download | rust-bdd0c9387bb10e0db01c00dcd47ea3e6bc343e45.tar.gz rust-bdd0c9387bb10e0db01c00dcd47ea3e6bc343e45.zip | |
get new decorator extensions working
Diffstat (limited to 'src/rustc/syntax')
| -rw-r--r-- | src/rustc/syntax/ext/base.rs | 3 | ||||
| -rw-r--r-- | src/rustc/syntax/ext/expand.rs | 48 | ||||
| -rw-r--r-- | src/rustc/syntax/fold.rs | 1 |
3 files changed, 52 insertions, 0 deletions
diff --git a/src/rustc/syntax/ext/base.rs b/src/rustc/syntax/ext/base.rs index d59591d849a..721f059ee35 100644 --- a/src/rustc/syntax/ext/base.rs +++ b/src/rustc/syntax/ext/base.rs @@ -11,10 +11,13 @@ type syntax_expander = { type macro_def = {ident: str, ext: syntax_extension}; type macro_definer = fn@(ext_ctxt, span, ast::mac_arg, ast::mac_body) -> macro_def; +type item_decorator = + fn@(ext_ctxt, span, ast::meta_item, [@ast::item]) -> [@ast::item]; enum syntax_extension { normal(syntax_expander), macro_defining(macro_definer), + item_decorator(item_decorator), } // A temporary hard-coded map of methods for expanding syntax extension diff --git a/src/rustc/syntax/ext/expand.rs b/src/rustc/syntax/ext/expand.rs index 104f49aebac..8384f7a8873 100644 --- a/src/rustc/syntax/ext/expand.rs +++ b/src/rustc/syntax/ext/expand.rs @@ -1,13 +1,17 @@ import driver::session; +import driver::session::session; import std::map::hashmap; +import front::attr; + import syntax::ast::{crate, expr_, expr_mac, mac_invoc}; import syntax::fold::*; import syntax::ext::base::*; import syntax::ext::qquote::{qq_helper}; import syntax::parse::parser::parse_expr_from_source_str; + import codemap::{span, expanded_from}; fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, @@ -26,6 +30,11 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, cx.span_fatal(pth.span, #fmt["macro undefined: '%s'", extname]) } + some(item_decorator(_)) { + cx.span_fatal( + pth.span, + #fmt["%s can only be used as a decorator", extname]); + } some(normal({expander: exp, span: exp_sp})) { let expanded = exp(cx, pth.span, args, body); @@ -52,6 +61,44 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, }; } +fn expand_mod_items(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, + module: ast::_mod, fld: ast_fold, + orig: fn@(ast::_mod, ast_fold) -> ast::_mod) + -> ast::_mod +{ + // Fold the contents first: + let module = orig(module, fld); + + // For each item, look through the attributes. If any of them are + // decorated with "item decorators", then use that function to transform + // the item into a new set of items. + let new_items = vec::flat_map(module.items) {|item| + vec::foldr(item.attrs, [item]) {|attr, items| + let mname = alt attr.node.value.node { + ast::meta_word(n) { n } + ast::meta_name_value(n, _) { n } + ast::meta_list(n, _) { n } + }; + alt exts.find(mname) { + none { items } + + some(normal(_)) | some(macro_defining(_)) { + cx.span_err( + attr.span, + #fmt["%s cannot be used as a decorator", mname]); + items + } + + some(item_decorator(dec_fn)) { + dec_fn(cx, attr.span, attr.node.value, items) + } + } + } + }; + + ret {items: new_items with module}; +} + fn new_span(cx: ext_ctxt, sp: span) -> span { /* this discards information in the case of macro-defining macros */ ret {lo: sp.lo, hi: sp.hi, expn_info: cx.backtrace()}; @@ -78,6 +125,7 @@ fn expand_crate(sess: session::session, c: @crate) -> @crate { let cx: ext_ctxt = mk_ctxt(sess); let f_pre = {fold_expr: bind expand_expr(exts, cx, _, _, _, afp.fold_expr), + fold_mod: bind expand_mod_items(exts, cx, _, _, afp.fold_mod), new_span: bind new_span(cx, _) with *afp}; let f = make_fold(f_pre); diff --git a/src/rustc/syntax/fold.rs b/src/rustc/syntax/fold.rs index f24f339590d..9e6ee76db9b 100644 --- a/src/rustc/syntax/fold.rs +++ b/src/rustc/syntax/fold.rs @@ -13,6 +13,7 @@ export noop_fold_mod; export noop_fold_ty; export noop_fold_block; export wrap; +export fold_ty_param; type ast_fold = @mutable a_f; |
