syntax: remove all remaining uses of #ast, and #ast / qquote itself.
This commit is contained in:
parent
80d6bc899b
commit
9cced55b93
11 changed files with 95 additions and 466 deletions
|
|
@ -1033,6 +1033,8 @@ fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item {
|
|||
trait fake_ext_ctxt {
|
||||
fn cfg() -> ast::crate_cfg;
|
||||
fn parse_sess() -> parse::parse_sess;
|
||||
fn call_site() -> span;
|
||||
fn ident_of(st: ~str) -> ast::ident;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -1042,6 +1044,16 @@ type fake_session = parse::parse_sess;
|
|||
impl fake_session: fake_ext_ctxt {
|
||||
fn cfg() -> ast::crate_cfg { ~[] }
|
||||
fn parse_sess() -> parse::parse_sess { self }
|
||||
fn call_site() -> span {
|
||||
codemap::span {
|
||||
lo: codemap::BytePos(0),
|
||||
hi: codemap::BytePos(0),
|
||||
expn_info: None
|
||||
}
|
||||
}
|
||||
fn ident_of(st: ~str) -> ast::ident {
|
||||
self.interner.intern(@st)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -1050,7 +1062,8 @@ fn mk_ctxt() -> fake_ext_ctxt {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn roundtrip(in_item: @ast::item) {
|
||||
fn roundtrip(in_item: Option<@ast::item>) {
|
||||
let in_item = in_item.get();
|
||||
let bytes = do io::with_bytes_writer |wr| {
|
||||
let ebml_w = writer::Serializer(wr);
|
||||
encode_item_ast(ebml_w, in_item);
|
||||
|
|
@ -1074,45 +1087,45 @@ fn roundtrip(in_item: @ast::item) {
|
|||
#[test]
|
||||
fn test_basic() {
|
||||
let ext_cx = mk_ctxt();
|
||||
roundtrip(#ast[item]{
|
||||
roundtrip(quote_item!(
|
||||
fn foo() {}
|
||||
});
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_smalltalk() {
|
||||
let ext_cx = mk_ctxt();
|
||||
roundtrip(#ast[item]{
|
||||
roundtrip(quote_item!(
|
||||
fn foo() -> int { 3 + 4 } // first smalltalk program ever executed.
|
||||
});
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_more() {
|
||||
let ext_cx = mk_ctxt();
|
||||
roundtrip(#ast[item]{
|
||||
roundtrip(quote_item!(
|
||||
fn foo(x: uint, y: uint) -> uint {
|
||||
let z = x + y;
|
||||
return z;
|
||||
}
|
||||
});
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_simplification() {
|
||||
let ext_cx = mk_ctxt();
|
||||
let item_in = ast::ii_item(#ast[item] {
|
||||
let item_in = ast::ii_item(quote_item!(
|
||||
fn new_int_alist<B: Copy>() -> alist<int, B> {
|
||||
fn eq_int(&&a: int, &&b: int) -> bool { a == b }
|
||||
return {eq_fn: eq_int, mut data: ~[]};
|
||||
}
|
||||
});
|
||||
).get());
|
||||
let item_out = simplify_ast(item_in);
|
||||
let item_exp = ast::ii_item(#ast[item] {
|
||||
let item_exp = ast::ii_item(quote_item!(
|
||||
fn new_int_alist<B: Copy>() -> alist<int, B> {
|
||||
return {eq_fn: eq_int, mut data: ~[]};
|
||||
}
|
||||
});
|
||||
).get());
|
||||
match (item_out, item_exp) {
|
||||
(ast::ii_item(item_out), ast::ii_item(item_exp)) => {
|
||||
assert pprust::item_to_str(item_out, ext_cx.parse_sess().interner)
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ priv impl ext_ctxt {
|
|||
fn lambda(blk: ast::blk) -> @ast::expr {
|
||||
let ext_cx = self;
|
||||
let blk_e = self.expr(blk.span, ast::expr_block(blk));
|
||||
#ast{ || $(blk_e) }
|
||||
quote_expr!( || $blk_e )
|
||||
}
|
||||
|
||||
fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk {
|
||||
|
|
|
|||
|
|
@ -109,8 +109,6 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
|
|||
syntax_expanders.insert(~"log_syntax",
|
||||
builtin_normal_tt(
|
||||
ext::log_syntax::expand_syntax_ext));
|
||||
syntax_expanders.insert(~"ast",
|
||||
builtin(ext::qquote::expand_ast));
|
||||
syntax_expanders.insert(~"deriving_eq",
|
||||
item_decorator(
|
||||
ext::deriving::expand_deriving_eq));
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ use ast::{crate, expr_, expr_mac, mac_invoc, mac_invoc_tt,
|
|||
tt_delim, tt_tok, item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi};
|
||||
use fold::*;
|
||||
use ext::base::*;
|
||||
use ext::qquote::{qq_helper};
|
||||
use parse::{parser, parse_expr_from_source_str, new_parser_from_tts};
|
||||
|
||||
|
||||
|
|
@ -169,7 +168,12 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt,
|
|||
None | Some(normal(_)) | Some(macro_defining(_))
|
||||
| Some(normal_tt(_)) | Some(item_tt(*)) => items,
|
||||
Some(item_decorator(dec_fn)) => {
|
||||
dec_fn(cx, attr.span, attr.node.value, items)
|
||||
cx.bt_push(ExpandedFrom({call_site: attr.span,
|
||||
callie: {name: copy mname,
|
||||
span: None}}));
|
||||
let r = dec_fn(cx, attr.span, attr.node.value, items);
|
||||
cx.bt_pop();
|
||||
r
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,370 +0,0 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use ast::{crate, expr_, mac_invoc,
|
||||
mac_aq, mac_var};
|
||||
use parse::parser;
|
||||
use parse::parser::{Parser, parse_from_source_str};
|
||||
use dvec::DVec;
|
||||
use parse::token::ident_interner;
|
||||
use codemap::{CharPos, BytePos};
|
||||
|
||||
use fold::*;
|
||||
use visit::*;
|
||||
use ext::base::*;
|
||||
use ext::build::*;
|
||||
use print::*;
|
||||
use io::*;
|
||||
|
||||
use codemap::span;
|
||||
|
||||
struct gather_item {
|
||||
lo: BytePos,
|
||||
hi: BytePos,
|
||||
e: @ast::expr,
|
||||
constr: ~str
|
||||
}
|
||||
|
||||
type aq_ctxt = @{lo: BytePos, gather: DVec<gather_item>};
|
||||
enum fragment {
|
||||
from_expr(@ast::expr),
|
||||
from_ty(@ast::Ty)
|
||||
}
|
||||
|
||||
fn ids_ext(cx: ext_ctxt, strs: ~[~str]) -> ~[ast::ident] {
|
||||
strs.map(|str| cx.parse_sess().interner.intern(@*str))
|
||||
}
|
||||
fn id_ext(cx: ext_ctxt, str: ~str) -> ast::ident {
|
||||
cx.parse_sess().interner.intern(@str)
|
||||
}
|
||||
|
||||
|
||||
trait qq_helper {
|
||||
fn span() -> span;
|
||||
fn visit(aq_ctxt, vt<aq_ctxt>);
|
||||
fn extract_mac() -> Option<ast::mac_>;
|
||||
fn mk_parse_fn(ext_ctxt,span) -> @ast::expr;
|
||||
fn get_fold_fn() -> ~str;
|
||||
}
|
||||
|
||||
impl @ast::crate: qq_helper {
|
||||
fn span() -> span {self.span}
|
||||
fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_crate(*self, cx, v);}
|
||||
fn extract_mac() -> Option<ast::mac_> {fail}
|
||||
fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
|
||||
mk_path(cx, sp,
|
||||
ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_crate"]))
|
||||
}
|
||||
fn get_fold_fn() -> ~str {~"fold_crate"}
|
||||
}
|
||||
impl @ast::expr: qq_helper {
|
||||
fn span() -> span {self.span}
|
||||
fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_expr(self, cx, v);}
|
||||
fn extract_mac() -> Option<ast::mac_> {
|
||||
match (self.node) {
|
||||
ast::expr_mac({node: ref mac, _}) => Some((*mac)),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
|
||||
mk_path(cx, sp,
|
||||
ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_expr"]))
|
||||
}
|
||||
fn get_fold_fn() -> ~str {~"fold_expr"}
|
||||
}
|
||||
impl @ast::Ty: qq_helper {
|
||||
fn span() -> span {self.span}
|
||||
fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_ty(self, cx, v);}
|
||||
fn extract_mac() -> Option<ast::mac_> {
|
||||
match (self.node) {
|
||||
ast::ty_mac({node: ref mac, _}) => Some((*mac)),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
|
||||
mk_path(cx, sp,
|
||||
ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_ty"]))
|
||||
}
|
||||
fn get_fold_fn() -> ~str {~"fold_ty"}
|
||||
}
|
||||
impl @ast::item: qq_helper {
|
||||
fn span() -> span {self.span}
|
||||
fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_item(self, cx, v);}
|
||||
fn extract_mac() -> Option<ast::mac_> {fail}
|
||||
fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
|
||||
mk_path(cx, sp,
|
||||
ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_item"]))
|
||||
}
|
||||
fn get_fold_fn() -> ~str {~"fold_item"}
|
||||
}
|
||||
impl @ast::stmt: qq_helper {
|
||||
fn span() -> span {self.span}
|
||||
fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_stmt(self, cx, v);}
|
||||
fn extract_mac() -> Option<ast::mac_> {fail}
|
||||
fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
|
||||
mk_path(cx, sp,
|
||||
ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_stmt"]))
|
||||
}
|
||||
fn get_fold_fn() -> ~str {~"fold_stmt"}
|
||||
}
|
||||
impl @ast::pat: qq_helper {
|
||||
fn span() -> span {self.span}
|
||||
fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_pat(self, cx, v);}
|
||||
fn extract_mac() -> Option<ast::mac_> {fail}
|
||||
fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
|
||||
mk_path(cx, sp, ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote",
|
||||
~"parse_pat"]))
|
||||
}
|
||||
fn get_fold_fn() -> ~str {~"fold_pat"}
|
||||
}
|
||||
|
||||
fn gather_anti_quotes<N: qq_helper>(lo: BytePos, node: N) -> aq_ctxt
|
||||
{
|
||||
let v = @{visit_expr: |node, &&cx, v| visit_aq(node, ~"from_expr", cx, v),
|
||||
visit_ty: |node, &&cx, v| visit_aq(node, ~"from_ty", cx, v),
|
||||
.. *default_visitor()};
|
||||
let cx = @{lo:lo, gather: DVec()};
|
||||
node.visit(cx, mk_vt(v));
|
||||
// FIXME (#2250): Maybe this is an overkill (merge_sort), it might
|
||||
// be better to just keep the gather array in sorted order.
|
||||
do cx.gather.swap |v| {
|
||||
pure fn by_lo(a: &gather_item, b: &gather_item) -> bool {
|
||||
a.lo < b.lo
|
||||
}
|
||||
std::sort::merge_sort(v, by_lo)
|
||||
};
|
||||
return cx;
|
||||
}
|
||||
|
||||
fn visit_aq<T:qq_helper>(node: T, constr: ~str, &&cx: aq_ctxt, v: vt<aq_ctxt>)
|
||||
{
|
||||
match (node.extract_mac()) {
|
||||
Some(mac_aq(sp, e)) => {
|
||||
cx.gather.push(gather_item {
|
||||
lo: sp.lo - cx.lo,
|
||||
hi: sp.hi - cx.lo,
|
||||
e: e,
|
||||
constr: constr});
|
||||
}
|
||||
_ => node.visit(cx, v)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_space(c: char) -> bool {
|
||||
parse::lexer::is_whitespace(c)
|
||||
}
|
||||
|
||||
fn expand_ast(ecx: ext_ctxt, _sp: span,
|
||||
arg: ast::mac_arg, body: ast::mac_body)
|
||||
-> @ast::expr
|
||||
{
|
||||
let mut what = ~"expr";
|
||||
do arg.iter |arg| {
|
||||
let args: ~[@ast::expr] =
|
||||
match arg.node {
|
||||
ast::expr_vec(elts, _) => elts,
|
||||
_ => {
|
||||
ecx.span_fatal
|
||||
(_sp, ~"#ast requires arguments of the form `~[...]`.")
|
||||
}
|
||||
};
|
||||
if vec::len::<@ast::expr>(args) != 1u {
|
||||
ecx.span_fatal(_sp, ~"#ast requires exactly one arg");
|
||||
}
|
||||
match (args[0].node) {
|
||||
ast::expr_path(@{idents: id, _}) if vec::len(id) == 1u
|
||||
=> what = *ecx.parse_sess().interner.get(id[0]),
|
||||
_ => ecx.span_fatal(args[0].span, ~"expected an identifier")
|
||||
}
|
||||
}
|
||||
let body = get_mac_body(ecx,_sp,body);
|
||||
|
||||
return match what {
|
||||
~"crate" => finish(ecx, body, parse_crate),
|
||||
~"expr" => finish(ecx, body, parse_expr),
|
||||
~"ty" => finish(ecx, body, parse_ty),
|
||||
~"item" => finish(ecx, body, parse_item),
|
||||
~"stmt" => finish(ecx, body, parse_stmt),
|
||||
~"pat" => finish(ecx, body, parse_pat),
|
||||
_ => ecx.span_fatal(_sp, ~"unsupported ast type")
|
||||
};
|
||||
}
|
||||
|
||||
fn parse_crate(p: Parser) -> @ast::crate { p.parse_crate_mod(~[]) }
|
||||
fn parse_ty(p: Parser) -> @ast::Ty { p.parse_ty(false) }
|
||||
fn parse_stmt(p: Parser) -> @ast::stmt { p.parse_stmt(~[]) }
|
||||
fn parse_expr(p: Parser) -> @ast::expr { p.parse_expr() }
|
||||
fn parse_pat(p: Parser) -> @ast::pat { p.parse_pat(true) }
|
||||
|
||||
fn parse_item(p: Parser) -> @ast::item {
|
||||
match p.parse_item(~[]) {
|
||||
Some(item) => item,
|
||||
None => fail ~"parse_item: parsing an item failed"
|
||||
}
|
||||
}
|
||||
|
||||
fn finish<T: qq_helper>
|
||||
(ecx: ext_ctxt, body: ast::mac_body_, f: fn (p: Parser) -> T)
|
||||
-> @ast::expr
|
||||
{
|
||||
let cm = ecx.codemap();
|
||||
let str = @cm.span_to_snippet(body.span);
|
||||
debug!("qquote--str==%?", str);
|
||||
let fname = cm.mk_substr_filename(body.span);
|
||||
let node = parse_from_source_str
|
||||
(f, fname, codemap::FssInternal(body.span), str,
|
||||
ecx.cfg(), ecx.parse_sess());
|
||||
let loc = cm.lookup_char_pos(body.span.lo);
|
||||
|
||||
let sp = node.span();
|
||||
let qcx = gather_anti_quotes(sp.lo, node);
|
||||
let cx = qcx;
|
||||
|
||||
for uint::range(1u, cx.gather.len()) |i| {
|
||||
assert cx.gather[i-1u].lo < cx.gather[i].lo;
|
||||
// ^^ check that the vector is sorted
|
||||
assert cx.gather[i-1u].hi <= cx.gather[i].lo;
|
||||
// ^^ check that the spans are non-overlapping
|
||||
}
|
||||
|
||||
let mut str2 = ~"";
|
||||
enum state {active, skip(uint), blank};
|
||||
let mut state = active;
|
||||
let mut i = BytePos(0u);
|
||||
let mut j = 0u;
|
||||
let g_len = cx.gather.len();
|
||||
for str::chars_each(*str) |ch| {
|
||||
if (j < g_len && i == cx.gather[j].lo) {
|
||||
assert ch == '$';
|
||||
let repl = fmt!("$%u ", j);
|
||||
state = skip(str::char_len(repl));
|
||||
str2 += repl;
|
||||
}
|
||||
match copy state {
|
||||
active => str::push_char(&mut str2, ch),
|
||||
skip(1u) => state = blank,
|
||||
skip(sk) => state = skip (sk-1u),
|
||||
blank if is_space(ch) => str::push_char(&mut str2, ch),
|
||||
blank => str::push_char(&mut str2, ' ')
|
||||
}
|
||||
i += BytePos(1u);
|
||||
if (j < g_len && i == cx.gather[j].hi) {
|
||||
assert ch == ')';
|
||||
state = active;
|
||||
j += 1u;
|
||||
}
|
||||
}
|
||||
|
||||
let cx = ecx;
|
||||
|
||||
let cfg_call = || mk_call_(
|
||||
cx, sp, mk_access(cx, sp, ids_ext(cx, ~[~"ext_cx"]),
|
||||
id_ext(cx, ~"cfg")), ~[]);
|
||||
|
||||
let parse_sess_call = || mk_call_(
|
||||
cx, sp, mk_access(cx, sp, ids_ext(cx, ~[~"ext_cx"]),
|
||||
id_ext(cx, ~"parse_sess")), ~[]);
|
||||
|
||||
let pcall = mk_call(cx,sp,
|
||||
ids_ext(cx, ~[~"syntax", ~"parse", ~"parser",
|
||||
~"parse_from_source_str"]),
|
||||
~[node.mk_parse_fn(cx,sp),
|
||||
mk_uniq_str(cx,sp, fname),
|
||||
mk_call(cx,sp,
|
||||
ids_ext(cx, ~[~"syntax",~"ext",
|
||||
~"qquote", ~"mk_file_substr"]),
|
||||
~[mk_uniq_str(cx,sp, loc.file.name),
|
||||
mk_uint(cx,sp, loc.line),
|
||||
mk_uint(cx,sp, loc.col.to_uint())]),
|
||||
mk_unary(cx,sp, ast::box(ast::m_imm),
|
||||
mk_uniq_str(cx,sp, str2)),
|
||||
cfg_call(),
|
||||
parse_sess_call()]
|
||||
);
|
||||
let mut rcall = pcall;
|
||||
if (g_len > 0u) {
|
||||
rcall = mk_call(cx,sp,
|
||||
ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote",
|
||||
~"replace"]),
|
||||
~[pcall,
|
||||
mk_uniq_vec_e(cx,sp, qcx.gather.map_to_vec(|g| {
|
||||
mk_call(cx,sp,
|
||||
ids_ext(cx, ~[~"syntax", ~"ext",
|
||||
~"qquote", g.constr]),
|
||||
~[g.e])})),
|
||||
mk_path(cx,sp,
|
||||
ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote",
|
||||
node.get_fold_fn()]))]);
|
||||
}
|
||||
return rcall;
|
||||
}
|
||||
|
||||
fn replace<T>(node: T, repls: ~[fragment], ff: fn (ast_fold, T) -> T)
|
||||
-> T
|
||||
{
|
||||
let aft = default_ast_fold();
|
||||
let f_pre = @{fold_expr: |a,b,c|replace_expr(repls, a, b, c,
|
||||
aft.fold_expr),
|
||||
fold_ty: |a,b,c|replace_ty(repls, a, b, c,
|
||||
aft.fold_ty),
|
||||
.. *aft};
|
||||
return ff(make_fold(f_pre), node);
|
||||
}
|
||||
fn fold_crate(f: ast_fold, &&n: @ast::crate) -> @ast::crate {
|
||||
@f.fold_crate(*n)
|
||||
}
|
||||
fn fold_expr(f: ast_fold, &&n: @ast::expr) -> @ast::expr {f.fold_expr(n)}
|
||||
fn fold_ty(f: ast_fold, &&n: @ast::Ty) -> @ast::Ty {f.fold_ty(n)}
|
||||
fn fold_item(f: ast_fold, &&n: @ast::item) -> @ast::item {
|
||||
f.fold_item(n).get() //HACK: we know we don't drop items
|
||||
}
|
||||
fn fold_stmt(f: ast_fold, &&n: @ast::stmt) -> @ast::stmt {f.fold_stmt(n)}
|
||||
fn fold_pat(f: ast_fold, &&n: @ast::pat) -> @ast::pat {f.fold_pat(n)}
|
||||
|
||||
fn replace_expr(repls: ~[fragment],
|
||||
e: ast::expr_, s: span, fld: ast_fold,
|
||||
orig: fn@(ast::expr_, span, ast_fold)->(ast::expr_, span))
|
||||
-> (ast::expr_, span)
|
||||
{
|
||||
match e {
|
||||
ast::expr_mac({node: mac_var(i), _}) => match (repls[i]) {
|
||||
from_expr(r) => (r.node, r.span),
|
||||
_ => fail /* fixme error message */
|
||||
},
|
||||
_ => orig(e,s,fld)
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_ty(repls: ~[fragment],
|
||||
e: ast::ty_, s: span, fld: ast_fold,
|
||||
orig: fn@(ast::ty_, span, ast_fold)->(ast::ty_, span))
|
||||
-> (ast::ty_, span)
|
||||
{
|
||||
match e {
|
||||
ast::ty_mac({node: mac_var(i), _}) => match (repls[i]) {
|
||||
from_ty(r) => (r.node, r.span),
|
||||
_ => fail /* fixme error message */
|
||||
},
|
||||
_ => orig(e,s,fld)
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_file_substr(fname: ~str, line: uint, col: uint) ->
|
||||
codemap::FileSubstr {
|
||||
codemap::FssExternal({filename: fname, line: line, col: CharPos(col)})
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
// fill-column: 78;
|
||||
// indent-tabs-mode: nil
|
||||
// c-basic-offset: 4
|
||||
// buffer-file-coding-system: utf-8-unix
|
||||
// End:
|
||||
|
|
@ -81,13 +81,6 @@ use ast::{_mod, add, arg, arm, attribute,
|
|||
|
||||
export Parser;
|
||||
|
||||
// FIXME (#3726): #ast expects to find this here but it's actually
|
||||
// defined in `parse` Fixing this will be easier when we have export
|
||||
// decls on individual items -- then parse can export this publicly, and
|
||||
// everything else crate-visibly.
|
||||
use parse::parse_from_source_str;
|
||||
export parse_from_source_str;
|
||||
|
||||
export item_or_view_item, iovi_none, iovi_view_item, iovi_item;
|
||||
|
||||
enum restriction {
|
||||
|
|
|
|||
|
|
@ -75,9 +75,6 @@ mod ext {
|
|||
#[legacy_exports]
|
||||
#[path = "ext/expand.rs"]
|
||||
mod expand;
|
||||
#[legacy_exports]
|
||||
#[path = "ext/qquote.rs"]
|
||||
mod qquote;
|
||||
|
||||
#[path = "ext/quote.rs"]
|
||||
mod quote;
|
||||
|
|
|
|||
|
|
@ -21,36 +21,44 @@ use syntax::codemap;
|
|||
use syntax::parse;
|
||||
use syntax::print::*;
|
||||
|
||||
fn new_parse_sess() -> parse::parse_sess {
|
||||
fail;
|
||||
}
|
||||
|
||||
trait fake_ext_ctxt {
|
||||
fn session() -> fake_session;
|
||||
fn cfg() -> ast::crate_cfg;
|
||||
fn parse_sess() -> parse::parse_sess;
|
||||
fn call_site() -> span;
|
||||
fn ident_of(st: ~str) -> ast::ident;
|
||||
}
|
||||
|
||||
type fake_options = {cfg: ast::crate_cfg};
|
||||
|
||||
type fake_session = {opts: @fake_options,
|
||||
parse_sess: parse::parse_sess};
|
||||
type fake_session = parse::parse_sess;
|
||||
|
||||
impl fake_session: fake_ext_ctxt {
|
||||
fn session() -> fake_session {self}
|
||||
fn cfg() -> ast::crate_cfg { ~[] }
|
||||
fn parse_sess() -> parse::parse_sess { self }
|
||||
fn call_site() -> span {
|
||||
codemap::span {
|
||||
lo: codemap::BytePos(0),
|
||||
hi: codemap::BytePos(0),
|
||||
expn_info: None
|
||||
}
|
||||
}
|
||||
fn ident_of(st: ~str) -> ast::ident {
|
||||
self.interner.intern(@st)
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_ctxt() -> fake_ext_ctxt {
|
||||
let opts : fake_options = {cfg: ~[]};
|
||||
{opts: @opts, parse_sess: new_parse_sess()} as fake_ext_ctxt
|
||||
parse::new_parse_sess(None) as fake_ext_ctxt
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn main() {
|
||||
let ext_cx = mk_ctxt();
|
||||
|
||||
let abc = #ast{23};
|
||||
let abc = quote_expr!(23);
|
||||
check_pp(abc, pprust::print_expr, "23");
|
||||
|
||||
let expr3 = #ast{2 - $(abcd) + 7}; //~ ERROR unresolved name: abcd
|
||||
let expr3 = quote_expr!(2 - $abcd + 7); //~ ERROR unresolved name: abcd
|
||||
check_pp(expr3, pprust::print_expr, "2 - 23 + 7");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,10 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// xfail-test Can't use syntax crate here
|
||||
|
||||
extern mod std;
|
||||
use syntax;
|
||||
extern mod syntax;
|
||||
|
||||
use std::io::*;
|
||||
|
||||
|
|
@ -20,33 +21,39 @@ use syntax::codemap;
|
|||
use syntax::parse::parser;
|
||||
use syntax::print::*;
|
||||
|
||||
fn new_parse_sess() -> parser::parse_sess {
|
||||
fail;
|
||||
}
|
||||
|
||||
trait fake_ext_ctxt {
|
||||
fn session() -> fake_session;
|
||||
fn cfg() -> ast::crate_cfg;
|
||||
fn parse_sess() -> parse::parse_sess;
|
||||
fn call_site() -> span;
|
||||
fn ident_of(st: ~str) -> ast::ident;
|
||||
}
|
||||
|
||||
type fake_options = {cfg: ast::crate_cfg};
|
||||
|
||||
type fake_session = {opts: @fake_options,
|
||||
parse_sess: parser::parse_sess};
|
||||
type fake_session = parse::parse_sess;
|
||||
|
||||
impl fake_session: fake_ext_ctxt {
|
||||
fn session() -> fake_session {self}
|
||||
fn cfg() -> ast::crate_cfg { ~[] }
|
||||
fn parse_sess() -> parse::parse_sess { self }
|
||||
fn call_site() -> span {
|
||||
codemap::span {
|
||||
lo: codemap::BytePos(0),
|
||||
hi: codemap::BytePos(0),
|
||||
expn_info: None
|
||||
}
|
||||
}
|
||||
fn ident_of(st: ~str) -> ast::ident {
|
||||
self.interner.intern(@st)
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_ctxt() -> fake_ext_ctxt {
|
||||
let opts : fake_options = {cfg: ~[]};
|
||||
{opts: @opts, parse_sess: new_parse_sess()} as fake_ext_ctxt
|
||||
parse::new_parse_sess(None) as fake_ext_ctxt
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let ext_cx = mk_ctxt();
|
||||
|
||||
let stmt = #ast[stmt]{let x int = 20;}; //~ ERROR expected end-of-string
|
||||
let stmt = quote_stmt!(let x int = 20;); //~ ERROR expected end-of-string
|
||||
check_pp(*stmt, pprust::print_stmt, "");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ fn mk_ctxt() -> fake_ext_ctxt {
|
|||
|
||||
fn main() {
|
||||
let ext_cx = mk_ctxt();
|
||||
let s = #ast[expr]{__s};
|
||||
let e = #ast[expr]{__e};
|
||||
let f = #ast[expr]{$(s).foo {|__e| $(e)}};
|
||||
let s = quote_expr!(__s);
|
||||
let e = quote_expr!(__e);
|
||||
let f = quote_expr!($s.foo {|__e| $e});
|
||||
log(error, pprust::expr_to_str(f));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,12 +20,16 @@ use io::*;
|
|||
use syntax::diagnostic;
|
||||
use syntax::ast;
|
||||
use syntax::codemap;
|
||||
use syntax::codemap::span;
|
||||
use syntax::parse;
|
||||
use syntax::print::*;
|
||||
|
||||
|
||||
trait fake_ext_ctxt {
|
||||
fn cfg() -> ast::crate_cfg;
|
||||
fn parse_sess() -> parse::parse_sess;
|
||||
fn call_site() -> span;
|
||||
fn ident_of(st: ~str) -> ast::ident;
|
||||
}
|
||||
|
||||
type fake_session = parse::parse_sess;
|
||||
|
|
@ -33,66 +37,41 @@ type fake_session = parse::parse_sess;
|
|||
impl fake_session: fake_ext_ctxt {
|
||||
fn cfg() -> ast::crate_cfg { ~[] }
|
||||
fn parse_sess() -> parse::parse_sess { self }
|
||||
fn call_site() -> span {
|
||||
codemap::span {
|
||||
lo: codemap::BytePos(0),
|
||||
hi: codemap::BytePos(0),
|
||||
expn_info: None
|
||||
}
|
||||
}
|
||||
fn ident_of(st: ~str) -> ast::ident {
|
||||
self.interner.intern(@copy st)
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_ctxt() -> fake_ext_ctxt {
|
||||
parse::new_parse_sess(None) as fake_ext_ctxt
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let ext_cx = mk_ctxt();
|
||||
|
||||
let abc = #ast{23};
|
||||
let abc = quote_expr!(23);
|
||||
check_pp(ext_cx, abc, pprust::print_expr, ~"23");
|
||||
|
||||
let expr3 = #ast{2 - $(abc) + 7};
|
||||
check_pp(ext_cx, expr3, pprust::print_expr, ~"2 - 23 + 7");
|
||||
|
||||
let expr4 = #ast{2 - $(#ast{3}) + 9};
|
||||
check_pp(ext_cx, expr4, pprust::print_expr, ~"2 - 3 + 9");
|
||||
|
||||
let ty = #ast[ty]{int};
|
||||
let ty = quote_ty!(int);
|
||||
check_pp(ext_cx, ty, pprust::print_type, ~"int");
|
||||
|
||||
let ty2 = #ast[ty]{option<$(ty)>};
|
||||
check_pp(ext_cx, ty2, pprust::print_type, ~"option<int>");
|
||||
|
||||
let item = #ast[item]{const x : int = 10;};
|
||||
let item = quote_item!(const x : int = 10;).get();
|
||||
check_pp(ext_cx, item, pprust::print_item, ~"const x: int = 10;");
|
||||
|
||||
let item2: @ast::item = #ast[item]{const x : int = $(abc);};
|
||||
check_pp(ext_cx, item2, pprust::print_item, ~"const x: int = 23;");
|
||||
|
||||
let stmt = #ast[stmt]{let x = 20;};
|
||||
let stmt = quote_stmt!(let x = 20;);
|
||||
check_pp(ext_cx, *stmt, pprust::print_stmt, ~"let x = 20;");
|
||||
|
||||
let stmt2 = #ast[stmt]{let x : $(ty) = $(abc);};
|
||||
check_pp(ext_cx, *stmt2, pprust::print_stmt, ~"let x: int = 23;");
|
||||
|
||||
let pat = #ast[pat]{some(_)};
|
||||
let pat = quote_pat!(some(_));
|
||||
check_pp(ext_cx, pat, pprust::print_refutable_pat, ~"some(_)");
|
||||
|
||||
// issue #1785
|
||||
let x = #ast{1};
|
||||
let test1 = #ast{1+$(x)};
|
||||
check_pp(ext_cx, test1, pprust::print_expr, ~"1 + 1");
|
||||
|
||||
let test2 = #ast{$(x)+1};
|
||||
check_pp(ext_cx, test2, pprust::print_expr, ~"1 + 1");
|
||||
|
||||
let y = #ast{2};
|
||||
let test3 = #ast{$(x) + $(y)};
|
||||
check_pp(ext_cx, test3, pprust::print_expr, ~"1 + 2");
|
||||
|
||||
let crate = #ast[crate] { fn a() { } };
|
||||
check_pp(ext_cx, crate, pprust::print_crate_, ~"fn a() { }\n");
|
||||
|
||||
// issue #1926
|
||||
let s = #ast[expr]{__s};
|
||||
let e = #ast[expr]{__e};
|
||||
let call = #ast[expr]{$(s).foo(|__e| $(e) )};
|
||||
check_pp(ext_cx, call, pprust::print_expr, ~"__s.foo(|__e| __e)")
|
||||
}
|
||||
|
||||
fn check_pp<T>(cx: fake_ext_ctxt,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue