syntax: Introduce a struct MacArgs
for macro arguments
This commit is contained in:
parent
fdc0011561
commit
a81804b4d5
19 changed files with 192 additions and 112 deletions
|
@ -27,7 +27,7 @@ pub use syntax_pos::symbol::{Ident, Symbol as Name};
|
|||
use crate::ptr::P;
|
||||
use crate::source_map::{dummy_spanned, respan, Spanned};
|
||||
use crate::token::{self, DelimToken};
|
||||
use crate::tokenstream::TokenStream;
|
||||
use crate::tokenstream::{TokenStream, TokenTree, DelimSpan};
|
||||
|
||||
use syntax_pos::symbol::{kw, sym, Symbol};
|
||||
use syntax_pos::{Span, DUMMY_SP, ExpnId};
|
||||
|
@ -40,6 +40,7 @@ use rustc_index::vec::Idx;
|
|||
use rustc_serialize::{self, Decoder, Encoder};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
|
||||
use std::iter;
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1372,21 +1373,71 @@ pub enum Movability {
|
|||
Movable,
|
||||
}
|
||||
|
||||
/// Represents a macro invocation. The `Path` indicates which macro
|
||||
/// is being invoked, and the vector of token-trees contains the source
|
||||
/// of the macro invocation.
|
||||
///
|
||||
/// N.B., the additional ident for a `macro_rules`-style macro is actually
|
||||
/// stored in the enclosing item.
|
||||
/// Represents a macro invocation. The `path` indicates which macro
|
||||
/// is being invoked, and the `args` are arguments passed to it.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct Mac {
|
||||
pub path: Path,
|
||||
pub delim: MacDelimiter,
|
||||
pub tts: TokenStream,
|
||||
pub args: P<MacArgs>,
|
||||
pub span: Span,
|
||||
pub prior_type_ascription: Option<(Span, bool)>,
|
||||
}
|
||||
|
||||
/// Arguments passed to an attribute or a function-like macro.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub enum MacArgs {
|
||||
/// No arguments - `#[attr]`.
|
||||
Empty,
|
||||
/// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`.
|
||||
Delimited(DelimSpan, MacDelimiter, TokenStream),
|
||||
/// Arguments of a key-value attribute - `#[attr = "value"]`.
|
||||
/// Span belongs to the `=` token, token stream is the "value".
|
||||
Eq(Span, TokenStream),
|
||||
}
|
||||
|
||||
impl MacArgs {
|
||||
pub fn delim(&self) -> DelimToken {
|
||||
match self {
|
||||
MacArgs::Delimited(_, delim, _) => delim.to_token(),
|
||||
MacArgs::Empty | MacArgs::Eq(..) => token::NoDelim,
|
||||
}
|
||||
}
|
||||
|
||||
/// Tokens inside the delimiters or after `=`.
|
||||
/// Proc macros see these tokens, for example.
|
||||
pub fn inner_tokens(&self) -> TokenStream {
|
||||
match self {
|
||||
MacArgs::Empty => TokenStream::default(),
|
||||
MacArgs::Delimited(.., tokens) => tokens.clone(),
|
||||
MacArgs::Eq(.., tokens) => tokens.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Tokens together with the delimiters or `=`.
|
||||
/// Use of this functions generally means that something suspicious or hacky is happening.
|
||||
pub fn outer_tokens(&self) -> TokenStream {
|
||||
match *self {
|
||||
MacArgs::Empty => TokenStream::default(),
|
||||
MacArgs::Delimited(dspan, delim, ref tokens) =>
|
||||
TokenTree::Delimited(dspan, delim.to_token(), tokens.clone()).into(),
|
||||
MacArgs::Eq(eq_span, ref tokens) => iter::once(TokenTree::token(token::Eq, eq_span))
|
||||
.chain(tokens.trees()).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether a macro with these arguments needs a semicolon
|
||||
/// when used as a standalone item or statement.
|
||||
pub fn need_semicolon(&self) -> bool {
|
||||
!matches!(self, MacArgs::Delimited(_, MacDelimiter::Brace ,_))
|
||||
}
|
||||
}
|
||||
|
||||
impl Mac {
|
||||
pub fn stream(&self) -> TokenStream {
|
||||
self.args.inner_tokens()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub enum MacDelimiter {
|
||||
Parenthesis,
|
||||
|
@ -1394,12 +1445,6 @@ pub enum MacDelimiter {
|
|||
Brace,
|
||||
}
|
||||
|
||||
impl Mac {
|
||||
pub fn stream(&self) -> TokenStream {
|
||||
self.tts.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl MacDelimiter {
|
||||
crate fn to_token(self) -> DelimToken {
|
||||
match self {
|
||||
|
@ -1408,6 +1453,15 @@ impl MacDelimiter {
|
|||
MacDelimiter::Brace => DelimToken::Brace,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_token(delim: DelimToken) -> MacDelimiter {
|
||||
match delim {
|
||||
token::Paren => MacDelimiter::Parenthesis,
|
||||
token::Bracket => MacDelimiter::Bracket,
|
||||
token::Brace => MacDelimiter::Brace,
|
||||
token::NoDelim => panic!("expected a delimiter"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a macro definition.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue