| use rustc_ast::ast; |
| use rustc_ast::ptr::P; |
| use rustc_ast::token; |
| use rustc_ast::tokenstream::TokenStream; |
| use rustc_parse::exp; |
| use rustc_span::symbol; |
| |
| use crate::rewrite::RewriteContext; |
| |
| pub(crate) fn parse_lazy_static( |
| context: &RewriteContext<'_>, |
| ts: TokenStream, |
| ) -> Option<Vec<(ast::Visibility, symbol::Ident, P<ast::Ty>, P<ast::Expr>)>> { |
| let mut result = vec![]; |
| let mut parser = super::build_parser(context, ts); |
| macro_rules! parse_or { |
| ($method:ident $(,)* $($arg:expr),* $(,)*) => { |
| match parser.$method($($arg,)*) { |
| Ok(val) => { |
| if parser.psess.dcx().has_errors().is_some() { |
| parser.psess.dcx().reset_err_count(); |
| return None; |
| } else { |
| val |
| } |
| } |
| Err(err) => { |
| err.cancel(); |
| parser.psess.dcx().reset_err_count(); |
| return None; |
| } |
| } |
| } |
| } |
| while parser.token.kind != token::Eof { |
| // Parse a `lazy_static!` item. |
| // FIXME: These `eat_*` calls should be converted to `parse_or` to avoid |
| // silently formatting malformed lazy-statics. |
| let vis = parse_or!(parse_visibility, rustc_parse::parser::FollowedByType::No); |
| let _ = parser.eat_keyword(exp!(Static)); |
| let _ = parser.eat_keyword(exp!(Ref)); |
| let id = parse_or!(parse_ident); |
| let _ = parser.eat(exp!(Colon)); |
| let ty = parse_or!(parse_ty); |
| let _ = parser.eat(exp!(Eq)); |
| let expr = parse_or!(parse_expr); |
| let _ = parser.eat(exp!(Semi)); |
| result.push((vis, id, ty, expr)); |
| } |
| |
| Some(result) |
| } |