Skip to content

Commit 07e7754

Browse files
committed
add #mod[], which expands to the current module path
1 parent 88f4d06 commit 07e7754

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed

src/librustsyntax/ext/base.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ fn syntax_expander_table() -> hashmap<str, syntax_extension> {
5353
builtin(ext::source_util::expand_stringify));
5454
syntax_expanders.insert("include",
5555
builtin(ext::source_util::expand_include));
56+
syntax_expanders.insert("mod",
57+
builtin(ext::source_util::expand_mod));
5658
ret syntax_expanders;
5759
}
5860

@@ -62,6 +64,9 @@ iface ext_ctxt {
6264
fn cfg() -> ast::crate_cfg;
6365
fn print_backtrace();
6466
fn backtrace() -> expn_info;
67+
fn mod_push(mod_name: ast::ident);
68+
fn mod_pop();
69+
fn mod_path() -> [ast::ident];
6570
fn bt_push(ei: codemap::expn_info_);
6671
fn bt_pop();
6772
fn span_fatal(sp: span, msg: str) -> !;
@@ -76,13 +81,17 @@ fn mk_ctxt(parse_sess: parse::parse_sess,
7681
cfg: ast::crate_cfg) -> ext_ctxt {
7782
type ctxt_repr = {parse_sess: parse::parse_sess,
7883
cfg: ast::crate_cfg,
79-
mut backtrace: expn_info};
84+
mut backtrace: expn_info,
85+
mut mod_path: [ast::ident]};
8086
impl of ext_ctxt for ctxt_repr {
8187
fn codemap() -> codemap { self.parse_sess.cm }
8288
fn parse_sess() -> parse::parse_sess { self.parse_sess }
8389
fn cfg() -> ast::crate_cfg { self.cfg }
8490
fn print_backtrace() { }
8591
fn backtrace() -> expn_info { self.backtrace }
92+
fn mod_push(i: ast::ident) { vec::push(self.mod_path, i); }
93+
fn mod_pop() { vec::pop(self.mod_path); }
94+
fn mod_path() -> [ast::ident] { ret self.mod_path; }
8695
fn bt_push(ei: codemap::expn_info_) {
8796
alt ei {
8897
expanded_from({call_site: cs, callie: callie}) {
@@ -129,7 +138,8 @@ fn mk_ctxt(parse_sess: parse::parse_sess,
129138
let imp : ctxt_repr = {
130139
parse_sess: parse_sess,
131140
cfg: cfg,
132-
mut backtrace: none
141+
mut backtrace: none,
142+
mut mod_path: []
133143
};
134144
ret imp as ext_ctxt
135145
}

src/librustsyntax/ext/expand.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,21 @@ fn expand_mod_items(exts: hashmap<str, syntax_extension>, cx: ext_ctxt,
8989
ret {items: new_items with module};
9090
}
9191

92+
/* record module we enter for `#mod` */
93+
fn expand_item(cx: ext_ctxt, &&it: @ast::item, fld: ast_fold,
94+
orig: fn@(&&@ast::item, ast_fold) -> @ast::item)
95+
-> @ast::item
96+
{
97+
let is_mod = alt it.node {
98+
ast::item_mod(_) | ast::item_native_mod(_) {true}
99+
_ {false}
100+
};
101+
if is_mod { cx.mod_push(it.ident); }
102+
let ret_val = orig(it, fld);
103+
if is_mod { cx.mod_pop(); }
104+
ret ret_val;
105+
}
106+
92107
fn new_span(cx: ext_ctxt, sp: span) -> span {
93108
/* this discards information in the case of macro-defining macros */
94109
ret {lo: sp.lo, hi: sp.hi, expn_info: cx.backtrace()};
@@ -117,6 +132,7 @@ fn expand_crate(parse_sess: parse::parse_sess,
117132
let f_pre =
118133
{fold_expr: bind expand_expr(exts, cx, _, _, _, afp.fold_expr),
119134
fold_mod: bind expand_mod_items(exts, cx, _, _, afp.fold_mod),
135+
fold_item: bind expand_item(cx, _, _, afp.fold_item),
120136
new_span: bind new_span(cx, _)
121137
with *afp};
122138
let f = make_fold(f_pre);

src/librustsyntax/ext/source_util.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import ast;
33
import codemap::span;
44
import print::pprust;
55

6-
76
/* #line(): expands to the current line number */
87
fn expand_line(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
98
_body: ast::mac_body) -> @ast::expr {
@@ -46,3 +45,9 @@ fn expand_include(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
4645
parse::parser::SOURCE_FILE);
4746
ret parse::parser::parse_expr(p)
4847
}
48+
49+
fn expand_mod(cx: ext_ctxt, sp: span, arg: ast::mac_arg, _body: ast::mac_body)
50+
-> @ast::expr {
51+
get_mac_args(cx, sp, arg, 0u, option::some(0u), "file");
52+
ret make_new_lit(cx, sp, ast::lit_str(str::connect(cx.mod_path(), "::")));
53+
}
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
// This test is brittle!
22
// xfail-pretty - the pretty tests lose path information, breaking #include
33

4+
mod m1 {
5+
mod m2 {
6+
fn where_am_i() -> str { #mod[] }
7+
}
8+
}
9+
410
fn main() {
5-
assert(#line[] == 5u);
11+
assert(#line[] == 11u);
612
assert(#col[] == 12u);
713
assert(#file[].ends_with("syntax-extension-source-utils.rs"));
814
assert(#stringify[(2*3) + 5] == "2 * 3 + 5");
915
assert(#include["syntax-extension-source-utils-files/includeme.fragment"]
10-
== "victory robot 6")
16+
== "victory robot 6");
17+
// The Windows tests are wrapped in an extra module for some reason
18+
assert(m1::m2::where_am_i().ends_with("m1::m2"));
1119
}

0 commit comments

Comments
 (0)