Skip to content

Commit c144752

Browse files
committed
Support multiple item macros
Closes #4375
1 parent 09f84aa commit c144752

File tree

12 files changed

+180
-124
lines changed

12 files changed

+180
-124
lines changed

src/librustc/front/config.rs

+12-22
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,6 @@ pub fn strip_items(crate: ast::Crate,
4848
ctxt.fold_crate(crate)
4949
}
5050

51-
fn filter_item(cx: &Context, item: @ast::item) -> Option<@ast::item> {
52-
if item_in_cfg(cx, item) {
53-
Some(item)
54-
} else {
55-
None
56-
}
57-
}
58-
5951
fn filter_view_item<'r>(cx: &Context, view_item: &'r ast::view_item)
6052
-> Option<&'r ast::view_item> {
6153
if view_item_in_cfg(cx, view_item) {
@@ -66,9 +58,10 @@ fn filter_view_item<'r>(cx: &Context, view_item: &'r ast::view_item)
6658
}
6759

6860
fn fold_mod(cx: &Context, m: &ast::_mod) -> ast::_mod {
69-
let filtered_items = m.items.iter().filter_map(|a| {
70-
filter_item(cx, *a).and_then(|x| cx.fold_item(x))
71-
}).collect();
61+
let filtered_items = m.items.iter()
62+
.filter(|&a| item_in_cfg(cx, *a))
63+
.flat_map(|&x| cx.fold_item(x).move_iter())
64+
.collect();
7265
let filtered_view_items = m.view_items.iter().filter_map(|a| {
7366
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
7467
}).collect();
@@ -122,28 +115,25 @@ fn fold_item_underscore(cx: &Context, item: &ast::item_) -> ast::item_ {
122115
fold::noop_fold_item_underscore(&item, cx)
123116
}
124117

125-
fn filter_stmt(cx: &Context, stmt: @ast::Stmt) -> Option<@ast::Stmt> {
118+
fn retain_stmt(cx: &Context, stmt: @ast::Stmt) -> bool {
126119
match stmt.node {
127120
ast::StmtDecl(decl, _) => {
128121
match decl.node {
129122
ast::DeclItem(item) => {
130-
if item_in_cfg(cx, item) {
131-
Some(stmt)
132-
} else {
133-
None
134-
}
123+
item_in_cfg(cx, item)
135124
}
136-
_ => Some(stmt)
125+
_ => true
137126
}
138127
}
139-
_ => Some(stmt),
128+
_ => true
140129
}
141130
}
142131

143132
fn fold_block(cx: &Context, b: &ast::Block) -> ast::Block {
144-
let resulting_stmts = b.stmts.iter().filter_map(|a| {
145-
filter_stmt(cx, *a).and_then(|stmt| cx.fold_stmt(stmt))
146-
}).collect();
133+
let resulting_stmts = b.stmts.iter()
134+
.filter(|&a| retain_stmt(cx, *a))
135+
.flat_map(|&stmt| cx.fold_stmt(stmt).move_iter())
136+
.collect();
147137
let filtered_view_items = b.view_items.iter().filter_map(|a| {
148138
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
149139
}).collect();

src/librustc/front/std_inject.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use syntax::codemap;
1919
use syntax::fold::ast_fold;
2020
use syntax::fold;
2121
use syntax::opt_vec;
22+
use syntax::util::small_vector::SmallVector;
2223

2324
static STD_VERSION: &'static str = "0.9-pre";
2425

@@ -98,14 +99,14 @@ impl fold::ast_fold for StandardLibraryInjector {
9899
}
99100
}
100101

101-
fn fold_item(&self, item: @ast::item) -> Option<@ast::item> {
102+
fn fold_item(&self, item: @ast::item) -> SmallVector<@ast::item> {
102103
if !no_prelude(item.attrs) {
103104
// only recur if there wasn't `#[no_implicit_prelude];`
104105
// on this item, i.e. this means that the prelude is not
105106
// implicitly imported though the whole subtree
106107
fold::noop_fold_item(item, self)
107108
} else {
108-
Some(item)
109+
SmallVector::one(item)
109110
}
110111
}
111112

src/librustc/front/test.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use syntax::fold;
2626
use syntax::opt_vec;
2727
use syntax::print::pprust;
2828
use syntax::{ast, ast_util};
29+
use syntax::util::small_vector::SmallVector;
2930

3031
struct Test {
3132
span: Span,
@@ -76,7 +77,7 @@ impl fold::ast_fold for TestHarnessGenerator {
7677
}
7778
}
7879

79-
fn fold_item(&self, i: @ast::item) -> Option<@ast::item> {
80+
fn fold_item(&self, i: @ast::item) -> SmallVector<@ast::item> {
8081
self.cx.path.push(i.ident);
8182
debug!("current path: {}",
8283
ast_util::path_name_i(self.cx.path.clone()));
@@ -108,7 +109,7 @@ impl fold::ast_fold for TestHarnessGenerator {
108109

109110
let res = fold::noop_fold_item(i, self);
110111
self.cx.path.pop();
111-
return res;
112+
res
112113
}
113114

114115
fn fold_mod(&self, m: &ast::_mod) -> ast::_mod {

src/librustc/middle/astencode.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use syntax::codemap;
3333
use syntax::fold::*;
3434
use syntax::fold;
3535
use syntax::parse::token;
36+
use syntax::util::small_vector::SmallVector;
3637
use syntax;
3738

3839
use std::at_vec;
@@ -347,13 +348,20 @@ fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item {
347348

348349
match *ii {
349350
//hack: we're not dropping items
350-
ast::ii_item(i) => ast::ii_item(fld.fold_item(i).unwrap()),
351+
ast::ii_item(i) => ast::ii_item(get_only_one(fld.fold_item(i))),
351352
ast::ii_method(d, is_provided, m) =>
352353
ast::ii_method(d, is_provided, fld.fold_method(m)),
353354
ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i))
354355
}
355356
}
356357

358+
fn get_only_one<T>(mut v: SmallVector<T>) -> T {
359+
if v.len() != 1 {
360+
fail!("Attempting to extract unique member but there isn't one");
361+
}
362+
v.pop()
363+
}
364+
357365
fn decode_ast(par_doc: ebml::Doc) -> ast::inlined_item {
358366
let chi_doc = par_doc.get(c::tag_tree as uint);
359367
let mut d = reader::Decoder(chi_doc);
@@ -379,7 +387,7 @@ fn renumber_ast(xcx: @ExtendedDecodeContext, ii: ast::inlined_item)
379387
xcx: xcx,
380388
};
381389
match ii {
382-
ast::ii_item(i) => ast::ii_item(fld.fold_item(i).unwrap()),
390+
ast::ii_item(i) => ast::ii_item(get_only_one(fld.fold_item(i))),
383391
ast::ii_method(d, is_provided, m) =>
384392
ast::ii_method(xcx.tr_def_id(d), is_provided, fld.fold_method(m)),
385393
ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i)),

src/librustpkg/util.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use syntax::{ast, attr, codemap, diagnostic, fold, visit};
2222
use syntax::attr::AttrMetaMethods;
2323
use syntax::fold::ast_fold;
2424
use syntax::visit::Visitor;
25+
use syntax::util::small_vector::SmallVector;
2526
use rustc::back::link::output_type_exe;
2627
use rustc::back::link;
2728
use rustc::driver::session::{lib_crate, bin_crate};
@@ -99,7 +100,7 @@ fn fold_mod(_ctx: @mut ReadyCtx, m: &ast::_mod, fold: &CrateSetup)
99100
}
100101

101102
fn fold_item(ctx: @mut ReadyCtx, item: @ast::item, fold: &CrateSetup)
102-
-> Option<@ast::item> {
103+
-> SmallVector<@ast::item> {
103104
ctx.path.push(item.ident);
104105

105106
let mut cmds = ~[];
@@ -142,7 +143,7 @@ struct CrateSetup {
142143
}
143144

144145
impl fold::ast_fold for CrateSetup {
145-
fn fold_item(&self, item: @ast::item) -> Option<@ast::item> {
146+
fn fold_item(&self, item: @ast::item) -> SmallVector<@ast::item> {
146147
fold_item(self.ctx, item, self)
147148
}
148149
fn fold_mod(&self, module: &ast::_mod) -> ast::_mod {

src/libsyntax/ext/base.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use ext::expand;
1818
use parse;
1919
use parse::token;
2020
use parse::token::{ident_to_str, intern, str_to_ident};
21+
use util::small_vector::SmallVector;
2122

2223
use std::hashmap::HashMap;
2324

@@ -131,7 +132,7 @@ pub type SyntaxExpanderTTItemFunNoCtxt =
131132

132133
pub trait AnyMacro {
133134
fn make_expr(&self) -> @ast::Expr;
134-
fn make_item(&self) -> Option<@ast::item>;
135+
fn make_items(&self) -> SmallVector<@ast::item>;
135136
fn make_stmt(&self) -> @ast::Stmt;
136137
}
137138

0 commit comments

Comments
 (0)