Skip to content

Commit

Permalink
syntax: Support modern attribute syntax in the meta matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Aug 17, 2019
1 parent 12e6bea commit d73c85e
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 56 deletions.
20 changes: 13 additions & 7 deletions src/libsyntax/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,8 @@ impl MetaItem {
}
}

impl Attribute {
/// Extracts the MetaItem from inside this Attribute.
pub fn meta(&self) -> Option<MetaItem> {
impl AttrItem {
crate fn meta(&self, span: Span) -> Option<MetaItem> {
let mut tokens = self.tokens.trees().peekable();
Some(MetaItem {
path: self.path.clone(),
Expand All @@ -268,9 +267,16 @@ impl Attribute {
} else {
return None;
},
span: self.span,
span,
})
}
}

impl Attribute {
/// Extracts the MetaItem from inside this Attribute.
pub fn meta(&self) -> Option<MetaItem> {
self.item.meta(self.span)
}

pub fn parse<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, T>
where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
Expand Down Expand Up @@ -501,7 +507,7 @@ impl MetaItem {
}
Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt {
token::Nonterminal::NtIdent(ident, _) => Path::from_ident(ident),
token::Nonterminal::NtMeta(ref meta) => return Some(meta.clone()),
token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
token::Nonterminal::NtPath(ref path) => path.clone(),
_ => return None,
},
Expand Down Expand Up @@ -725,7 +731,7 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -
);

let start_span = parser.token.span;
let (path, tokens) = panictry!(parser.parse_meta_item_unrestricted());
let item = panictry!(parser.parse_attr_item());
let end_span = parser.token.span;
if parser.token != token::Eof {
parse_sess.span_diagnostic
Expand All @@ -734,7 +740,7 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -
}

krate.attrs.push(Attribute {
item: AttrItem { path, tokens },
item,
id: mk_attr_id(),
style: AttrStyle::Inner,
is_sugared_doc: false,
Expand Down
8 changes: 4 additions & 4 deletions src/libsyntax/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ impl<'a> StripUnconfigured<'a> {

while !parser.check(&token::CloseDelim(token::Paren)) {
let lo = parser.token.span.lo();
let (path, tokens) = parser.parse_meta_item_unrestricted()?;
expanded_attrs.push((path, tokens, parser.prev_span.with_lo(lo)));
let item = parser.parse_attr_item()?;
expanded_attrs.push((item, parser.prev_span.with_lo(lo)));
parser.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Paren)])?;
}

Expand All @@ -150,8 +150,8 @@ impl<'a> StripUnconfigured<'a> {
// `cfg_attr` inside of another `cfg_attr`. E.g.
// `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
expanded_attrs.into_iter()
.flat_map(|(path, tokens, span)| self.process_cfg_attr(ast::Attribute {
item: ast::AttrItem { path, tokens },
.flat_map(|(item, span)| self.process_cfg_attr(ast::Attribute {
item,
id: attr::mk_attr_id(),
style: attr.style,
is_sugared_doc: false,
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/tt/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Nonterminal {
FatalError.raise()
}
sym::path => token::NtPath(panictry!(p.parse_path(PathStyle::Type))),
sym::meta => token::NtMeta(panictry!(p.parse_meta_item())),
sym::meta => token::NtMeta(panictry!(p.parse_attr_item())),
sym::vis => token::NtVis(panictry!(p.parse_visibility(true))),
sym::lifetime => if p.check_lifetime() {
token::NtLifetime(p.expect_lifetime().ident)
Expand Down
5 changes: 4 additions & 1 deletion src/libsyntax/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,10 @@ pub fn noop_visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis:
token::NtIdent(ident, _is_raw) => vis.visit_ident(ident),
token::NtLifetime(ident) => vis.visit_ident(ident),
token::NtLiteral(expr) => vis.visit_expr(expr),
token::NtMeta(meta) => vis.visit_meta_item(meta),
token::NtMeta(AttrItem { path, tokens }) => {
vis.visit_path(path);
vis.visit_tts(tokens);
}
token::NtPath(path) => vis.visit_path(path),
token::NtTT(tt) => vis.visit_tt(tt),
token::NtImplItem(item) =>
Expand Down
31 changes: 18 additions & 13 deletions src/libsyntax/parse/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl<'a> Parser<'a> {
debug!("parse_attribute_with_inner_parse_policy: inner_parse_policy={:?} self.token={:?}",
inner_parse_policy,
self.token);
let (span, path, tokens, style) = match self.token.kind {
let (span, item, style) = match self.token.kind {
token::Pound => {
let lo = self.token.span;
self.bump();
Expand All @@ -115,7 +115,7 @@ impl<'a> Parser<'a> {
};

self.expect(&token::OpenDelim(token::Bracket))?;
let (path, tokens) = self.parse_meta_item_unrestricted()?;
let item = self.parse_attr_item()?;
self.expect(&token::CloseDelim(token::Bracket))?;
let hi = self.prev_span;

Expand Down Expand Up @@ -150,7 +150,7 @@ impl<'a> Parser<'a> {
}
}

(attr_sp, path, tokens, style)
(attr_sp, item, style)
}
_ => {
let token_str = self.this_token_to_string();
Expand All @@ -159,7 +159,7 @@ impl<'a> Parser<'a> {
};

Ok(ast::Attribute {
item: ast::AttrItem { path, tokens },
item,
id: attr::mk_attr_id(),
style,
is_sugared_doc: false,
Expand All @@ -176,17 +176,17 @@ impl<'a> Parser<'a> {
/// PATH
/// PATH `=` TOKEN_TREE
/// The delimiters or `=` are still put into the resulting token stream.
crate fn parse_meta_item_unrestricted(&mut self) -> PResult<'a, (ast::Path, TokenStream)> {
let meta = match self.token.kind {
crate fn parse_attr_item(&mut self) -> PResult<'a, ast::AttrItem> {
let item = match self.token.kind {
token::Interpolated(ref nt) => match **nt {
Nonterminal::NtMeta(ref meta) => Some(meta.clone()),
Nonterminal::NtMeta(ref item) => Some(item.clone()),
_ => None,
},
_ => None,
};
Ok(if let Some(meta) = meta {
Ok(if let Some(item) = item {
self.bump();
(meta.path, meta.node.tokens(meta.span))
item
} else {
let path = self.parse_path(PathStyle::Mod)?;
let tokens = if self.check(&token::OpenDelim(DelimToken::Paren)) ||
Expand All @@ -213,7 +213,7 @@ impl<'a> Parser<'a> {
} else {
TokenStream::empty()
};
(path, tokens)
ast::AttrItem { path, tokens }
})
}

Expand Down Expand Up @@ -281,9 +281,14 @@ impl<'a> Parser<'a> {
_ => None,
};

if let Some(meta) = nt_meta {
self.bump();
return Ok(meta);
if let Some(item) = nt_meta {
return match item.meta(item.path.span) {
Some(meta) => {
self.bump();
Ok(meta)
}
None => self.unexpected(),
}
}

let lo = self.token.span;
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/parse/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ impl<'a> Parser<'a> {
pub fn parse_path_allowing_meta(&mut self, style: PathStyle) -> PResult<'a, Path> {
let meta_ident = match self.token.kind {
token::Interpolated(ref nt) => match **nt {
token::NtMeta(ref meta) => match meta.node {
ast::MetaItemKind::Word => Some(meta.path.clone()),
_ => None,
token::NtMeta(ref item) => match item.tokens.is_empty() {
true => Some(item.path.clone()),
false => None,
},
_ => None,
},
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ pub enum Nonterminal {
NtLifetime(ast::Ident),
NtLiteral(P<ast::Expr>),
/// Stuff inside brackets for attributes
NtMeta(ast::MetaItem),
NtMeta(ast::AttrItem),
NtPath(ast::Path),
NtVis(ast::Visibility),
NtTT(TokenTree),
Expand Down
40 changes: 22 additions & 18 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String {
crate fn nonterminal_to_string(nt: &Nonterminal) -> String {
match *nt {
token::NtExpr(ref e) => expr_to_string(e),
token::NtMeta(ref e) => meta_item_to_string(e),
token::NtMeta(ref e) => attr_item_to_string(e),
token::NtTy(ref e) => ty_to_string(e),
token::NtPath(ref e) => path_to_string(e),
token::NtItem(ref e) => item_to_string(e),
Expand Down Expand Up @@ -398,8 +398,8 @@ pub fn meta_list_item_to_string(li: &ast::NestedMetaItem) -> String {
to_string(|s| s.print_meta_list_item(li))
}

pub fn meta_item_to_string(mi: &ast::MetaItem) -> String {
to_string(|s| s.print_meta_item(mi))
fn attr_item_to_string(ai: &ast::AttrItem) -> String {
to_string(|s| s.print_attr_item(ai, ai.path.span))
}

pub fn attribute_to_string(attr: &ast::Attribute) -> String {
Expand Down Expand Up @@ -603,24 +603,28 @@ pub trait PrintState<'a>: std::ops::Deref<Target=pp::Printer> + std::ops::DerefM
ast::AttrStyle::Inner => self.word("#!["),
ast::AttrStyle::Outer => self.word("#["),
}
self.ibox(0);
match attr.tokens.trees().next() {
Some(TokenTree::Delimited(_, delim, tts)) => {
self.print_mac_common(
Some(MacHeader::Path(&attr.path)), false, None, delim, tts, true, attr.span
);
}
tree => {
self.print_path(&attr.path, false, 0);
if tree.is_some() {
self.space();
self.print_tts(attr.tokens.clone(), true);
}
self.print_attr_item(&attr.item, attr.span);
self.word("]");
}
}

fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
self.ibox(0);
match item.tokens.trees().next() {
Some(TokenTree::Delimited(_, delim, tts)) => {
self.print_mac_common(
Some(MacHeader::Path(&item.path)), false, None, delim, tts, true, span
);
}
tree => {
self.print_path(&item.path, false, 0);
if tree.is_some() {
self.space();
self.print_tts(item.tokens.clone(), true);
}
}
self.end();
self.word("]");
}
self.end();
}

fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) {
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/cfg/cfg_stmt_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fn main() {
// check that macro expanded code works

macro_rules! if_cfg {
($cfg:meta $ib:block else $eb:block) => {
($cfg:meta? $ib:block else $eb:block) => {
{
let r;
#[cfg($cfg)]
Expand All @@ -69,7 +69,7 @@ fn main() {
}
}

let n = if_cfg!(unset {
let n = if_cfg!(unset? {
413
} else {
612
Expand Down
6 changes: 0 additions & 6 deletions src/test/ui/macros/macro-first-set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,6 @@ test_path!(::std);
test_path!(std::u8,);
test_path!(any, super, super::super::self::path, X<Y>::Z<'a, T=U>);

macro_rules! test_meta_block {
($($m:meta)* $b:block) => {};
}

test_meta_block!(windows {});

macro_rules! test_lifetime {
(1. $($l:lifetime)* $($b:block)*) => {};
(2. $($b:block)* $($l:lifetime)*) => {};
Expand Down

0 comments on commit d73c85e

Please sign in to comment.