Skip to content

Commit 8b40ead

Browse files
committed
Refactor parse_expansion out of ResultAnyMacro.
1 parent 5fc14c1 commit 8b40ead

File tree

2 files changed

+63
-92
lines changed

2 files changed

+63
-92
lines changed

src/libsyntax/ext/expand.rs

+51-4
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ use ext::base::*;
2121
use feature_gate::{self, Features};
2222
use fold;
2323
use fold::*;
24-
use parse::{ParseSess, lexer};
24+
use parse::{ParseSess, PResult, lexer};
2525
use parse::parser::Parser;
26-
use parse::token::{intern, keywords};
26+
use parse::token::{self, intern, keywords};
2727
use print::pprust;
2828
use ptr::P;
2929
use tokenstream::{TokenTree, TokenStream};
@@ -38,12 +38,12 @@ macro_rules! expansions {
3838
($($kind:ident: $ty:ty [$($vec:ident, $ty_elt:ty)*], $kind_name:expr, .$make:ident,
3939
$(.$fold:ident)* $(lift .$fold_elt:ident)*,
4040
$(.$visit:ident)* $(lift .$visit_elt:ident)*;)*) => {
41-
#[derive(Copy, Clone)]
41+
#[derive(Copy, Clone, PartialEq, Eq)]
4242
pub enum ExpansionKind { OptExpr, $( $kind, )* }
4343
pub enum Expansion { OptExpr(Option<P<ast::Expr>>), $( $kind($ty), )* }
4444

4545
impl ExpansionKind {
46-
fn name(self) -> &'static str {
46+
pub fn name(self) -> &'static str {
4747
match self {
4848
ExpansionKind::OptExpr => "expression",
4949
$( ExpansionKind::$kind => $kind_name, )*
@@ -106,6 +106,12 @@ macro_rules! expansions {
106106
self.expand(Expansion::$kind(SmallVector::one(node))).$make()
107107
})*)*
108108
}
109+
110+
impl<'a> MacResult for ::ext::tt::macro_rules::ParserAnyMacro<'a> {
111+
$(fn $make(self: Box<::ext::tt::macro_rules::ParserAnyMacro<'a>>) -> Option<$ty> {
112+
Some(self.make(ExpansionKind::$kind).$make())
113+
})*
114+
}
109115
}
110116
}
111117

@@ -450,6 +456,47 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
450456
}
451457
}
452458

459+
impl<'a> Parser<'a> {
460+
pub fn parse_expansion(&mut self, kind: ExpansionKind) -> PResult<'a, Expansion> {
461+
Ok(match kind {
462+
ExpansionKind::Items => {
463+
let mut items = SmallVector::zero();
464+
while let Some(item) = self.parse_item()? {
465+
items.push(item);
466+
}
467+
Expansion::Items(items)
468+
}
469+
ExpansionKind::TraitItems => {
470+
let mut items = SmallVector::zero();
471+
while self.token != token::Eof {
472+
items.push(self.parse_trait_item()?);
473+
}
474+
Expansion::TraitItems(items)
475+
}
476+
ExpansionKind::ImplItems => {
477+
let mut items = SmallVector::zero();
478+
while self.token != token::Eof {
479+
items.push(self.parse_impl_item()?);
480+
}
481+
Expansion::ImplItems(items)
482+
}
483+
ExpansionKind::Stmts => {
484+
let mut stmts = SmallVector::zero();
485+
while self.token != token::Eof {
486+
if let Some(stmt) = self.parse_full_stmt(true)? {
487+
stmts.push(stmt);
488+
}
489+
}
490+
Expansion::Stmts(stmts)
491+
}
492+
ExpansionKind::Expr => Expansion::Expr(self.parse_expr()?),
493+
ExpansionKind::OptExpr => Expansion::OptExpr(Some(self.parse_expr()?)),
494+
ExpansionKind::Ty => Expansion::Ty(self.parse_ty()?),
495+
ExpansionKind::Pat => Expansion::Pat(self.parse_pat()?),
496+
})
497+
}
498+
}
499+
453500
struct InvocationCollector<'a, 'b: 'a> {
454501
cx: &'a mut ExtCtxt<'b>,
455502
cfg: StripUnconfigured<'a>,

src/libsyntax/ext/tt/macro_rules.rs

+12-88
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use {ast, attr};
1212
use syntax_pos::{Span, DUMMY_SP};
1313
use ext::base::{DummyResult, ExtCtxt, MacEager, MacResult, SyntaxExtension};
1414
use ext::base::{IdentMacroExpander, NormalTT, TTMacroExpander};
15+
use ext::expand::{Expansion, ExpansionKind};
1516
use ext::placeholders;
1617
use ext::tt::macro_parser::{Success, Error, Failure};
1718
use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
@@ -22,18 +23,14 @@ use parse::parser::{Parser, Restrictions};
2223
use parse::token::{self, gensym_ident, NtTT, Token};
2324
use parse::token::Token::*;
2425
use print;
25-
use ptr::P;
2626
use tokenstream::{self, TokenTree};
2727

28-
use util::small_vector::SmallVector;
29-
30-
use std::cell::RefCell;
3128
use std::collections::{HashMap};
3229
use std::collections::hash_map::{Entry};
3330
use std::rc::Rc;
3431

35-
struct ParserAnyMacro<'a> {
36-
parser: RefCell<Parser<'a>>,
32+
pub struct ParserAnyMacro<'a> {
33+
parser: Parser<'a>,
3734

3835
/// Span of the expansion site of the macro this parser is for
3936
site_span: Span,
@@ -48,8 +45,8 @@ impl<'a> ParserAnyMacro<'a> {
4845
/// about e.g. the semicolon in `macro_rules! kapow { () => {
4946
/// panic!(); } }` doesn't get picked up by .parse_expr(), but it's
5047
/// allowed to be there.
51-
fn ensure_complete_parse(&self, allow_semi: bool, context: &str) {
52-
let mut parser = self.parser.borrow_mut();
48+
fn ensure_complete_parse(&mut self, allow_semi: bool, context: &str) {
49+
let ParserAnyMacro { site_span, macro_ident, ref mut parser } = *self;
5350
parser.ensure_complete_parse(allow_semi, |parser| {
5451
let token_str = parser.this_token_to_string();
5552
let msg = format!("macro expansion ignores token `{}` and any \
@@ -59,89 +56,16 @@ impl<'a> ParserAnyMacro<'a> {
5956
let mut err = parser.diagnostic().struct_span_err(span, &msg);
6057
let msg = format!("caused by the macro expansion here; the usage \
6158
of `{}!` is likely invalid in {} context",
62-
self.macro_ident, context);
63-
err.span_note(self.site_span, &msg)
59+
macro_ident, context);
60+
err.span_note(site_span, &msg)
6461
.emit();
6562
});
6663
}
67-
}
68-
69-
impl<'a> MacResult for ParserAnyMacro<'a> {
70-
fn make_expr(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Expr>> {
71-
let ret = panictry!(self.parser.borrow_mut().parse_expr());
72-
self.ensure_complete_parse(true, "expression");
73-
Some(ret)
74-
}
75-
fn make_pat(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Pat>> {
76-
let ret = panictry!(self.parser.borrow_mut().parse_pat());
77-
self.ensure_complete_parse(false, "pattern");
78-
Some(ret)
79-
}
80-
fn make_items(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Item>>> {
81-
let mut ret = SmallVector::zero();
82-
while let Some(item) = panictry!(self.parser.borrow_mut().parse_item()) {
83-
ret.push(item);
84-
}
85-
self.ensure_complete_parse(false, "item");
86-
Some(ret)
87-
}
88-
89-
fn make_impl_items(self: Box<ParserAnyMacro<'a>>)
90-
-> Option<SmallVector<ast::ImplItem>> {
91-
let mut ret = SmallVector::zero();
92-
loop {
93-
let mut parser = self.parser.borrow_mut();
94-
match parser.token {
95-
token::Eof => break,
96-
_ => ret.push(panictry!(parser.parse_impl_item()))
97-
}
98-
}
99-
self.ensure_complete_parse(false, "item");
100-
Some(ret)
101-
}
102-
103-
fn make_trait_items(self: Box<ParserAnyMacro<'a>>)
104-
-> Option<SmallVector<ast::TraitItem>> {
105-
let mut ret = SmallVector::zero();
106-
loop {
107-
let mut parser = self.parser.borrow_mut();
108-
match parser.token {
109-
token::Eof => break,
110-
_ => ret.push(panictry!(parser.parse_trait_item()))
111-
}
112-
}
113-
self.ensure_complete_parse(false, "item");
114-
Some(ret)
115-
}
116-
117-
118-
fn make_stmts(self: Box<ParserAnyMacro<'a>>)
119-
-> Option<SmallVector<ast::Stmt>> {
120-
let mut ret = SmallVector::zero();
121-
loop {
122-
let mut parser = self.parser.borrow_mut();
123-
match parser.token {
124-
token::Eof => break,
125-
_ => match parser.parse_full_stmt(true) {
126-
Ok(maybe_stmt) => match maybe_stmt {
127-
Some(stmt) => ret.push(stmt),
128-
None => (),
129-
},
130-
Err(mut e) => {
131-
e.emit();
132-
break;
133-
}
134-
}
135-
}
136-
}
137-
self.ensure_complete_parse(false, "statement");
138-
Some(ret)
139-
}
14064

141-
fn make_ty(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Ty>> {
142-
let ret = panictry!(self.parser.borrow_mut().parse_ty());
143-
self.ensure_complete_parse(false, "type");
144-
Some(ret)
65+
pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: ExpansionKind) -> Expansion {
66+
let expansion = panictry!(self.parser.parse_expansion(kind));
67+
self.ensure_complete_parse(kind == ExpansionKind::Expr, kind.name());
68+
expansion
14569
}
14670
}
14771

@@ -219,7 +143,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
219143
// Let the context choose how to interpret the result.
220144
// Weird, but useful for X-macros.
221145
return Box::new(ParserAnyMacro {
222-
parser: RefCell::new(p),
146+
parser: p,
223147

224148
// Pass along the original expansion site and the name of the macro
225149
// so we can print a useful error message if the parse of the expanded

0 commit comments

Comments
 (0)