@@ -27,7 +27,7 @@ pub use syntax_pos::symbol::{Ident, Symbol as Name};
2727use crate :: ptr:: P ;
2828use crate :: source_map:: { dummy_spanned, respan, Spanned } ;
2929use crate :: token:: { self , DelimToken } ;
30- use crate :: tokenstream:: TokenStream ;
30+ use crate :: tokenstream:: { TokenStream , TokenTree , DelimSpan } ;
3131
3232use syntax_pos:: symbol:: { kw, sym, Symbol } ;
3333use syntax_pos:: { Span , DUMMY_SP , ExpnId } ;
@@ -40,6 +40,7 @@ use rustc_index::vec::Idx;
4040use rustc_serialize:: { self , Decoder , Encoder } ;
4141use rustc_macros:: HashStable_Generic ;
4242
43+ use std:: iter;
4344use std:: fmt;
4445
4546#[ cfg( test) ]
@@ -1372,34 +1373,78 @@ pub enum Movability {
13721373 Movable ,
13731374}
13741375
1375- /// Represents a macro invocation. The `Path` indicates which macro
1376- /// is being invoked, and the vector of token-trees contains the source
1377- /// of the macro invocation.
1378- ///
1379- /// N.B., the additional ident for a `macro_rules`-style macro is actually
1380- /// stored in the enclosing item.
1376+ /// Represents a macro invocation. The `path` indicates which macro
1377+ /// is being invoked, and the `args` are arguments passed to it.
13811378#[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
13821379pub struct Mac {
13831380 pub path : Path ,
1384- pub delim : MacDelimiter ,
1385- pub tts : TokenStream ,
1381+ pub args : P < MacArgs > ,
13861382 pub span : Span ,
13871383 pub prior_type_ascription : Option < ( Span , bool ) > ,
13881384}
13891385
1390- #[ derive( Copy , Clone , PartialEq , Eq , RustcEncodable , RustcDecodable , Debug ) ]
1391- pub enum MacDelimiter {
1392- Parenthesis ,
1393- Bracket ,
1394- Brace ,
1386+ /// Arguments passed to an attribute or a function-like macro.
1387+ #[ derive( Clone , RustcEncodable , RustcDecodable , Debug ) ]
1388+ pub enum MacArgs {
1389+ /// No arguments - `#[attr]`.
1390+ Empty ,
1391+ /// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`.
1392+ Delimited ( DelimSpan , MacDelimiter , TokenStream ) ,
1393+ /// Arguments of a key-value attribute - `#[attr = "value"]`.
1394+ /// Span belongs to the `=` token, token stream is the "value".
1395+ Eq ( Span , TokenStream ) ,
1396+ }
1397+
1398+ impl MacArgs {
1399+ pub fn delim ( & self ) -> DelimToken {
1400+ match self {
1401+ MacArgs :: Delimited ( _, delim, _) => delim. to_token ( ) ,
1402+ MacArgs :: Empty | MacArgs :: Eq ( ..) => token:: NoDelim ,
1403+ }
1404+ }
1405+
1406+ /// Tokens inside the delimiters or after `=`.
1407+ /// Proc macros see these tokens, for example.
1408+ pub fn inner_tokens ( & self ) -> TokenStream {
1409+ match self {
1410+ MacArgs :: Empty => TokenStream :: default ( ) ,
1411+ MacArgs :: Delimited ( .., tokens) => tokens. clone ( ) ,
1412+ MacArgs :: Eq ( .., tokens) => tokens. clone ( ) ,
1413+ }
1414+ }
1415+
1416+ /// Tokens together with the delimiters or `=`.
1417+ /// Use of this functions generally means that something suspicious or hacky is happening.
1418+ pub fn outer_tokens ( & self ) -> TokenStream {
1419+ match * self {
1420+ MacArgs :: Empty => TokenStream :: default ( ) ,
1421+ MacArgs :: Delimited ( dspan, delim, ref tokens) =>
1422+ TokenTree :: Delimited ( dspan, delim. to_token ( ) , tokens. clone ( ) ) . into ( ) ,
1423+ MacArgs :: Eq ( eq_span, ref tokens) => iter:: once ( TokenTree :: token ( token:: Eq , eq_span) )
1424+ . chain ( tokens. trees ( ) ) . collect ( ) ,
1425+ }
1426+ }
1427+
1428+ /// Whether a macro with these arguments needs a semicolon
1429+ /// when used as a standalone item or statement.
1430+ pub fn need_semicolon ( & self ) -> bool {
1431+ !matches ! ( self , MacArgs :: Delimited ( _, MacDelimiter :: Brace , _) )
1432+ }
13951433}
13961434
13971435impl Mac {
13981436 pub fn stream ( & self ) -> TokenStream {
1399- self . tts . clone ( )
1437+ self . args . inner_tokens ( )
14001438 }
14011439}
14021440
1441+ #[ derive( Copy , Clone , PartialEq , Eq , RustcEncodable , RustcDecodable , Debug ) ]
1442+ pub enum MacDelimiter {
1443+ Parenthesis ,
1444+ Bracket ,
1445+ Brace ,
1446+ }
1447+
14031448impl MacDelimiter {
14041449 crate fn to_token ( self ) -> DelimToken {
14051450 match self {
@@ -1408,6 +1453,15 @@ impl MacDelimiter {
14081453 MacDelimiter :: Brace => DelimToken :: Brace ,
14091454 }
14101455 }
1456+
1457+ pub fn from_token ( delim : DelimToken ) -> MacDelimiter {
1458+ match delim {
1459+ token:: Paren => MacDelimiter :: Parenthesis ,
1460+ token:: Bracket => MacDelimiter :: Bracket ,
1461+ token:: Brace => MacDelimiter :: Brace ,
1462+ token:: NoDelim => panic ! ( "expected a delimiter" ) ,
1463+ }
1464+ }
14111465}
14121466
14131467/// Represents a macro definition.
0 commit comments