Skip to content

Commit

Permalink
auto merge of rust-lang#8556 : sfackler/rust/quote, r=alexcrichton
Browse files Browse the repository at this point in the history
They previously required one called "ext_cx" to be in scope.

Fixes part of rust-lang#7727
  • Loading branch information
bors committed Aug 19, 2013
2 parents 557ff04 + 8b80922 commit c178b52
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 186 deletions.
110 changes: 110 additions & 0 deletions src/librustc/front/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ fn mk_std(cx: &TestCtxt) -> ast::view_item {
}
}

#[cfg(stage0)]
fn mk_test_module(cx: &TestCtxt) -> @ast::item {

// Link to extra
Expand Down Expand Up @@ -334,6 +335,48 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::item {

return @item;
}
#[cfg(not(stage0))]
fn mk_test_module(cx: &TestCtxt) -> @ast::item {

// Link to extra
let view_items = ~[mk_std(cx)];

// A constant vector of test descriptors.
let tests = mk_tests(cx);

// The synthesized main function which will call the console test runner
// with our list of tests
let mainfn = (quote_item!(cx.ext_cx,
pub fn main() {
#[main];
extra::test::test_main_static(::std::os::args(), TESTS);
}
)).unwrap();

let testmod = ast::_mod {
view_items: view_items,
items: ~[mainfn, tests],
};
let item_ = ast::item_mod(testmod);

// This attribute tells resolve to let us call unexported functions
let resolve_unexported_attr =
attr::mk_attr(attr::mk_word_item(@"!resolve_unexported"));

let item = ast::item {
ident: cx.sess.ident_of("__test"),
attrs: ~[resolve_unexported_attr],
id: cx.sess.next_node_id(),
node: item_,
vis: ast::public,
span: dummy_sp(),
};

debug!("Synthetic test module:\n%s\n",
pprust::item_to_str(@item.clone(), cx.sess.intr()));

return @item;
}

fn nospan<T>(t: T) -> codemap::spanned<T> {
codemap::spanned { node: t, span: dummy_sp() }
Expand All @@ -355,6 +398,7 @@ fn path_node_global(ids: ~[ast::ident]) -> ast::Path {
types: ~[] }
}

#[cfg(stage0)]
fn mk_tests(cx: &TestCtxt) -> @ast::item {

let ext_cx = cx.ext_cx;
Expand All @@ -368,6 +412,17 @@ fn mk_tests(cx: &TestCtxt) -> @ast::item {
;
)).unwrap()
}
#[cfg(not(stage0))]
fn mk_tests(cx: &TestCtxt) -> @ast::item {
// The vector of test_descs for this crate
let test_descs = mk_test_descs(cx);

(quote_item!(cx.ext_cx,
pub static TESTS : &'static [self::extra::test::TestDescAndFn] =
$test_descs
;
)).unwrap()
}

fn is_extra(cx: &TestCtxt) -> bool {
let items = attr::find_linkage_metas(cx.crate.attrs);
Expand Down Expand Up @@ -398,6 +453,7 @@ fn mk_test_descs(cx: &TestCtxt) -> @ast::expr {
}
}

#[cfg(stage0)]
fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::expr {
let span = test.span;
let path = test.path.clone();
Expand Down Expand Up @@ -453,3 +509,57 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::expr {
);
e
}
#[cfg(not(stage0))]
fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> @ast::expr {
let span = test.span;
let path = test.path.clone();

debug!("encoding %s", ast_util::path_name_i(path));

let name_lit: ast::lit =
nospan(ast::lit_str(ast_util::path_name_i(path).to_managed()));

let name_expr = @ast::expr {
id: cx.sess.next_node_id(),
node: ast::expr_lit(@name_lit),
span: span
};

let fn_path = path_node_global(path);

let fn_expr = @ast::expr {
id: cx.sess.next_node_id(),
node: ast::expr_path(fn_path),
span: span,
};

let t_expr = if test.bench {
quote_expr!(cx.ext_cx, self::extra::test::StaticBenchFn($fn_expr) )
} else {
quote_expr!(cx.ext_cx, self::extra::test::StaticTestFn($fn_expr) )
};

let ignore_expr = if test.ignore {
quote_expr!(cx.ext_cx, true )
} else {
quote_expr!(cx.ext_cx, false )
};

let fail_expr = if test.should_fail {
quote_expr!(cx.ext_cx, true )
} else {
quote_expr!(cx.ext_cx, false )
};

let e = quote_expr!(cx.ext_cx,
self::extra::test::TestDescAndFn {
desc: self::extra::test::TestDesc {
name: self::extra::test::StaticTestName($name_expr),
ignore: $ignore_expr,
should_fail: $fail_expr
},
testfn: $t_expr,
}
);
e
}
18 changes: 9 additions & 9 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1288,24 +1288,24 @@ fn roundtrip(in_item: Option<@ast::item>) {

#[test]
fn test_basic() {
let ext_cx = mk_ctxt();
roundtrip(quote_item!(
let cx = mk_ctxt();
roundtrip(quote_item!(cx,
fn foo() {}
));
}

#[test]
fn test_smalltalk() {
let ext_cx = mk_ctxt();
roundtrip(quote_item!(
let cx = mk_ctxt();
roundtrip(quote_item!(cx,
fn foo() -> int { 3 + 4 } // first smalltalk program ever executed.
));
}

#[test]
fn test_more() {
let ext_cx = mk_ctxt();
roundtrip(quote_item!(
let cx = mk_ctxt();
roundtrip(quote_item!(cx,
fn foo(x: uint, y: uint) -> uint {
let z = x + y;
return z;
Expand All @@ -1315,15 +1315,15 @@ fn test_more() {

#[test]
fn test_simplification() {
let ext_cx = mk_ctxt();
let item_in = ast::ii_item(quote_item!(
let cx = mk_ctxt();
let item_in = ast::ii_item(quote_item!(cx,
fn new_int_alist<B>() -> alist<int, B> {
fn eq_int(a: int, b: int) -> bool { a == b }
return alist {eq_fn: eq_int, data: ~[]};
}
).unwrap());
let item_out = simplify_ast(&item_in);
let item_exp = ast::ii_item(quote_item!(
let item_exp = ast::ii_item(quote_item!(cx,
fn new_int_alist<B>() -> alist<int, B> {
return alist {eq_fn: eq_int, data: ~[]};
}
Expand Down
12 changes: 12 additions & 0 deletions src/libsyntax/ext/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,17 +605,29 @@ impl AstBuilder for @ExtCtxt {

self.expr(span, ast::expr_fn_block(fn_decl, blk))
}
#[cfg(stage0)]
fn lambda0(&self, _span: span, blk: ast::Block) -> @ast::expr {
let ext_cx = *self;
let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
quote_expr!(|| $blk_e )
}
#[cfg(not(stage0))]
fn lambda0(&self, _span: span, blk: ast::Block) -> @ast::expr {
let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
quote_expr!(*self, || $blk_e )
}

#[cfg(stage0)]
fn lambda1(&self, _span: span, blk: ast::Block, ident: ast::ident) -> @ast::expr {
let ext_cx = *self;
let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
quote_expr!(|$ident| $blk_e )
}
#[cfg(not(stage0))]
fn lambda1(&self, _span: span, blk: ast::Block, ident: ast::ident) -> @ast::expr {
let blk_e = self.expr(blk.span, ast::expr_block(blk.clone()));
quote_expr!(*self, |$ident| $blk_e )
}

fn lambda_expr(&self, span: span, ids: ~[ast::ident], expr: @ast::expr) -> @ast::expr {
self.lambda(span, ids, self.block_expr(expr))
Expand Down
28 changes: 20 additions & 8 deletions src/libsyntax/ext/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use ext::build::AstBuilder;

use std::os;

#[cfg(stage0)]
pub fn expand_option_env(ext_cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
-> base::MacResult {
let var = get_single_str_from_tts(ext_cx, sp, tts, "option_env!");
Expand All @@ -32,25 +33,36 @@ pub fn expand_option_env(ext_cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
};
MRExpr(e)
}
#[cfg(not(stage0))]
pub fn expand_option_env(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
-> base::MacResult {
let var = get_single_str_from_tts(cx, sp, tts, "option_env!");

let e = match os::getenv(var) {
None => quote_expr!(cx, ::std::option::None::<&'static str>),
Some(s) => quote_expr!(cx, ::std::option::Some($s))
};
MRExpr(e)
}

pub fn expand_env(ext_cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
pub fn expand_env(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
-> base::MacResult {
let exprs = get_exprs_from_tts(ext_cx, sp, tts);
let exprs = get_exprs_from_tts(cx, sp, tts);

if exprs.len() == 0 {
ext_cx.span_fatal(sp, "env! takes 1 or 2 arguments");
cx.span_fatal(sp, "env! takes 1 or 2 arguments");
}

let var = expr_to_str(ext_cx, exprs[0], "expected string literal");
let var = expr_to_str(cx, exprs[0], "expected string literal");
let msg = match exprs.len() {
1 => fmt!("Environment variable %s not defined", var).to_managed(),
2 => expr_to_str(ext_cx, exprs[1], "expected string literal"),
_ => ext_cx.span_fatal(sp, "env! takes 1 or 2 arguments")
2 => expr_to_str(cx, exprs[1], "expected string literal"),
_ => cx.span_fatal(sp, "env! takes 1 or 2 arguments")
};

let e = match os::getenv(var) {
None => ext_cx.span_fatal(sp, msg),
Some(s) => ext_cx.expr_str(sp, s.to_managed())
None => cx.span_fatal(sp, msg),
Some(s) => cx.expr_str(sp, s.to_managed())
};
MRExpr(e)
}
Loading

0 comments on commit c178b52

Please sign in to comment.