syntax/attr: reduce reliance on parser
This commit is contained in:
parent
b7176b44a2
commit
16329402bf
6 changed files with 36 additions and 32 deletions
|
@ -15,7 +15,7 @@ use crate::ast::{Lit, LitKind, Expr, Item, Local, Stmt, StmtKind, GenericParam};
|
|||
use crate::mut_visit::visit_clobber;
|
||||
use crate::source_map::{BytePos, Spanned};
|
||||
use crate::parse::lexer::comments::doc_comment_style;
|
||||
use crate::parse::parser::Parser;
|
||||
use crate::parse;
|
||||
use crate::parse::PResult;
|
||||
use crate::parse::token::{self, Token};
|
||||
use crate::ptr::P;
|
||||
|
@ -280,35 +280,10 @@ impl Attribute {
|
|||
self.item.meta(self.span)
|
||||
}
|
||||
|
||||
crate fn parse<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, T>
|
||||
where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
||||
{
|
||||
let mut parser = Parser::new(
|
||||
sess,
|
||||
self.tokens.clone(),
|
||||
None,
|
||||
false,
|
||||
false,
|
||||
Some("attribute"),
|
||||
);
|
||||
let result = f(&mut parser)?;
|
||||
if parser.token != token::Eof {
|
||||
parser.unexpected()?;
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn parse_derive_paths<'a>(&self, sess: &'a ParseSess) -> PResult<'a, Vec<Path>> {
|
||||
if self.tokens.is_empty() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
self.parse(sess, |p| p.parse_derive_paths())
|
||||
}
|
||||
|
||||
pub fn parse_meta<'a>(&self, sess: &'a ParseSess) -> PResult<'a, MetaItem> {
|
||||
Ok(MetaItem {
|
||||
path: self.path.clone(),
|
||||
kind: self.parse(sess, |parser| parser.parse_meta_item_kind())?,
|
||||
kind: parse::parse_in_attr(sess, self, |p| p.parse_meta_item_kind())?,
|
||||
span: self.span,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::attr;
|
|||
use crate::ast;
|
||||
use crate::edition::Edition;
|
||||
use crate::mut_visit::*;
|
||||
use crate::parse;
|
||||
use crate::ptr::P;
|
||||
use crate::sess::ParseSess;
|
||||
use crate::symbol::sym;
|
||||
|
@ -112,7 +113,8 @@ impl<'a> StripUnconfigured<'a> {
|
|||
return vec![];
|
||||
}
|
||||
|
||||
let (cfg_predicate, expanded_attrs) = match attr.parse(self.sess, |p| p.parse_cfg_attr()) {
|
||||
let res = parse::parse_in_attr(self.sess, &attr, |p| p.parse_cfg_attr());
|
||||
let (cfg_predicate, expanded_attrs) = match res {
|
||||
Ok(result) => result,
|
||||
Err(mut e) => {
|
||||
e.emit();
|
||||
|
|
|
@ -96,8 +96,7 @@ pub mod json;
|
|||
pub mod ast;
|
||||
pub mod attr;
|
||||
pub mod source_map;
|
||||
#[macro_use]
|
||||
pub mod config;
|
||||
#[macro_use] pub mod config;
|
||||
pub mod entry;
|
||||
pub mod feature_gate;
|
||||
pub mod mut_visit;
|
||||
|
|
|
@ -288,6 +288,27 @@ pub fn stream_to_parser_with_base_dir<'a>(
|
|||
Parser::new(sess, stream, Some(base_dir), true, false, None)
|
||||
}
|
||||
|
||||
/// Runs the given subparser `f` on the tokens of the given `attr`'s item.
|
||||
pub fn parse_in_attr<'a, T>(
|
||||
sess: &'a ParseSess,
|
||||
attr: &ast::Attribute,
|
||||
mut f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
|
||||
) -> PResult<'a, T> {
|
||||
let mut parser = Parser::new(
|
||||
sess,
|
||||
attr.tokens.clone(),
|
||||
None,
|
||||
false,
|
||||
false,
|
||||
Some("attribute"),
|
||||
);
|
||||
let result = f(&mut parser)?;
|
||||
if parser.token != token::Eof {
|
||||
parser.unexpected()?;
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// NOTE(Centril): The following probably shouldn't be here but it acknowledges the
|
||||
// fact that architecturally, we are using parsing (read on below to understand why).
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
/// Parse a list of paths inside `#[derive(path_0, ..., path_n)]`.
|
||||
crate fn parse_derive_paths(&mut self) -> PResult<'a, Vec<Path>> {
|
||||
pub fn parse_derive_paths(&mut self) -> PResult<'a, Vec<Path>> {
|
||||
self.expect(&token::OpenDelim(token::Paren))?;
|
||||
let mut list = Vec::new();
|
||||
while !self.eat(&token::CloseDelim(token::Paren)) {
|
||||
|
|
|
@ -200,7 +200,14 @@ crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>)
|
|||
return false;
|
||||
}
|
||||
|
||||
match attr.parse_derive_paths(cx.parse_sess) {
|
||||
let parse_derive_paths = |attr: &ast::Attribute| {
|
||||
if attr.tokens.is_empty() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
parse::parse_in_attr(cx.parse_sess, attr, |p| p.parse_derive_paths())
|
||||
};
|
||||
|
||||
match parse_derive_paths(attr) {
|
||||
Ok(traits) => {
|
||||
result.extend(traits);
|
||||
true
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue