diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-12-01 19:16:44 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-12-02 21:56:34 +0300 |
| commit | cf71538094b03c9c7116eceabc4985ab3b5e558a (patch) | |
| tree | aad0d7de53443bcc26f5c3c9cc20ca5ef8418c56 /src/libsyntax/attr | |
| parent | 537895535deaa766d59e44e1c9b941a8ad4adb10 (diff) | |
| download | rust-cf71538094b03c9c7116eceabc4985ab3b5e558a.tar.gz rust-cf71538094b03c9c7116eceabc4985ab3b5e558a.zip | |
syntax: Optimize conversion `AttrItem` -> `MetaItem` by avoiding `outer_tokens`.
Diffstat (limited to 'src/libsyntax/attr')
| -rw-r--r-- | src/libsyntax/attr/mod.rs | 73 |
1 files changed, 44 insertions, 29 deletions
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 080c7209d6b..079a0f6fafa 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -278,17 +278,9 @@ impl MetaItem { impl AttrItem { pub fn meta(&self, span: Span) -> Option<MetaItem> { - let mut tokens = self.args.outer_tokens().trees().peekable(); Some(MetaItem { path: self.path.clone(), - kind: if let Some(kind) = MetaItemKind::from_tokens(&mut tokens) { - if tokens.peek().is_some() { - return None; - } - kind - } else { - return None; - }, + kind: MetaItemKind::from_mac_args(&self.args)?, span, }) } @@ -567,26 +559,8 @@ impl MetaItemKind { } } - fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItemKind> - where I: Iterator<Item = TokenTree>, - { - let delimited = match tokens.peek().cloned() { - Some(TokenTree::Token(token)) if token == token::Eq => { - tokens.next(); - return if let Some(TokenTree::Token(token)) = tokens.next() { - Lit::from_token(&token).ok().map(MetaItemKind::NameValue) - } else { - None - }; - } - Some(TokenTree::Delimited(_, delim, ref tts)) if delim == token::Paren => { - tokens.next(); - tts.clone() - } - _ => return Some(MetaItemKind::Word), - }; - - let mut tokens = delimited.into_trees().peekable(); + fn list_from_tokens(tokens: TokenStream) -> Option<MetaItemKind> { + let mut tokens = tokens.into_trees().peekable(); let mut result = Vec::new(); while let Some(..) = tokens.peek() { let item = NestedMetaItem::from_tokens(&mut tokens)?; @@ -598,6 +572,47 @@ impl MetaItemKind { } Some(MetaItemKind::List(result)) } + + fn name_value_from_tokens( + tokens: &mut impl Iterator<Item = TokenTree>, + ) -> Option<MetaItemKind> { + match tokens.next() { + Some(TokenTree::Token(token)) => + Lit::from_token(&token).ok().map(MetaItemKind::NameValue), + _ => None, + } + } + + fn from_mac_args(args: &MacArgs) -> Option<MetaItemKind> { + match args { + MacArgs::Delimited(_, MacDelimiter::Parenthesis, tokens) => + MetaItemKind::list_from_tokens(tokens.clone()), + MacArgs::Delimited(..) => None, + MacArgs::Eq(_, tokens) => { + assert!(tokens.len() == 1); + MetaItemKind::name_value_from_tokens(&mut tokens.trees()) + } + MacArgs::Empty => Some(MetaItemKind::Word), + } + } + + fn from_tokens( + tokens: &mut iter::Peekable<impl Iterator<Item = TokenTree>>, + ) -> Option<MetaItemKind> { + match tokens.peek() { + Some(TokenTree::Delimited(_, token::Paren, inner_tokens)) => { + let inner_tokens = inner_tokens.clone(); + tokens.next(); + MetaItemKind::list_from_tokens(inner_tokens) + } + Some(TokenTree::Delimited(..)) => None, + Some(TokenTree::Token(Token { kind: token::Eq, .. })) => { + tokens.next(); + MetaItemKind::name_value_from_tokens(tokens) + } + _ => Some(MetaItemKind::Word), + } + } } impl NestedMetaItem { |
