Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor inner attribute parsing #1021

Merged
merged 4 commits into from Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 8 additions & 14 deletions src/attr.rs
Expand Up @@ -250,9 +250,7 @@ impl Attribute {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
pub fn parse_inner(input: ParseStream) -> Result<Vec<Self>> {
let mut attrs = Vec::new();
while input.peek(Token![#]) && input.peek2(Token![!]) {
attrs.push(input.call(parsing::single_parse_inner)?);
}
parsing::parse_inner(input, &mut attrs)?;
Ok(attrs)
}
}
Expand Down Expand Up @@ -503,8 +501,13 @@ pub mod parsing {
use super::*;
use crate::ext::IdentExt;
use crate::parse::{Parse, ParseStream, Result};
#[cfg(feature = "full")]
use crate::private;

pub fn parse_inner(input: ParseStream, attrs: &mut Vec<Attribute>) -> Result<()> {
while input.peek(Token![#]) && input.peek2(Token![!]) {
attrs.push(input.call(parsing::single_parse_inner)?);
}
Ok(())
}

pub fn single_parse_inner(input: ParseStream) -> Result<Attribute> {
let content;
Expand All @@ -528,15 +531,6 @@ pub mod parsing {
})
}

#[cfg(feature = "full")]
impl private {
pub(crate) fn attrs(outer: Vec<Attribute>, inner: Vec<Attribute>) -> Vec<Attribute> {
let mut attrs = outer;
attrs.extend(inner);
attrs
}
}

// Like Path::parse_mod_style but accepts keywords in the path.
fn parse_meta_path(input: ParseStream) -> Result<Path> {
Ok(Path {
Expand Down
39 changes: 19 additions & 20 deletions src/expr.rs
Expand Up @@ -1524,15 +1524,15 @@ pub(crate) mod parsing {
// <atom> ? ...
#[cfg(feature = "full")]
fn trailer_expr(
outer_attrs: Vec<Attribute>,
mut attrs: Vec<Attribute>,
input: ParseStream,
allow_struct: AllowStruct,
) -> Result<Expr> {
let atom = atom_expr(input, allow_struct)?;
let mut e = trailer_helper(input, atom)?;

let inner_attrs = e.replace_attrs(Vec::new());
let attrs = private::attrs(outer_attrs, inner_attrs);
attrs.extend(inner_attrs);
e.replace_attrs(attrs);
Ok(e)
}
Expand Down Expand Up @@ -2141,7 +2141,7 @@ pub(crate) mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ExprForLoop {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let mut attrs = input.call(Attribute::parse_outer)?;
let label: Option<Label> = input.parse()?;
let for_token: Token![for] = input.parse()?;

Expand All @@ -2152,11 +2152,11 @@ pub(crate) mod parsing {

let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
attr::parsing::parse_inner(&content, &mut attrs)?;
let stmts = content.call(Block::parse_within)?;

Ok(ExprForLoop {
attrs: private::attrs(outer_attrs, inner_attrs),
attrs,
label,
for_token,
pat,
Expand All @@ -2171,17 +2171,17 @@ pub(crate) mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ExprLoop {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let mut attrs = input.call(Attribute::parse_outer)?;
let label: Option<Label> = input.parse()?;
let loop_token: Token![loop] = input.parse()?;

let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
attr::parsing::parse_inner(&content, &mut attrs)?;
let stmts = content.call(Block::parse_within)?;

Ok(ExprLoop {
attrs: private::attrs(outer_attrs, inner_attrs),
attrs,
label,
loop_token,
body: Block { brace_token, stmts },
Expand All @@ -2193,21 +2193,21 @@ pub(crate) mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ExprMatch {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let mut attrs = input.call(Attribute::parse_outer)?;
let match_token: Token![match] = input.parse()?;
let expr = Expr::parse_without_eager_brace(input)?;

let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
attr::parsing::parse_inner(&content, &mut attrs)?;

let mut arms = Vec::new();
while !content.is_empty() {
arms.push(content.call(Arm::parse)?);
}

Ok(ExprMatch {
attrs: private::attrs(outer_attrs, inner_attrs),
attrs,
match_token,
expr: Box::new(expr),
brace_token,
Expand Down Expand Up @@ -2487,18 +2487,18 @@ pub(crate) mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ExprWhile {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let mut attrs = input.call(Attribute::parse_outer)?;
let label: Option<Label> = input.parse()?;
let while_token: Token![while] = input.parse()?;
let cond = Expr::parse_without_eager_brace(input)?;

let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
attr::parsing::parse_inner(&content, &mut attrs)?;
let stmts = content.call(Block::parse_within)?;

Ok(ExprWhile {
attrs: private::attrs(outer_attrs, inner_attrs),
attrs,
label,
while_token,
cond: Box::new(cond),
Expand Down Expand Up @@ -2627,13 +2627,12 @@ pub(crate) mod parsing {
#[cfg(feature = "full")]
fn expr_struct_helper(
input: ParseStream,
outer_attrs: Vec<Attribute>,
mut attrs: Vec<Attribute>,
path: Path,
) -> Result<ExprStruct> {
let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
let attrs = private::attrs(outer_attrs, inner_attrs);
attr::parsing::parse_inner(&content, &mut attrs)?;

let mut fields = Punctuated::new();
while !content.is_empty() {
Expand Down Expand Up @@ -2706,16 +2705,16 @@ pub(crate) mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ExprBlock {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let mut attrs = input.call(Attribute::parse_outer)?;
let label: Option<Label> = input.parse()?;

let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
attr::parsing::parse_inner(&content, &mut attrs)?;
let stmts = content.call(Block::parse_within)?;

Ok(ExprBlock {
attrs: private::attrs(outer_attrs, inner_attrs),
attrs,
label,
block: Block { brace_token, stmts },
})
Expand Down
44 changes: 22 additions & 22 deletions src/item.rs
Expand Up @@ -1533,17 +1533,17 @@ pub mod parsing {

fn parse_rest_of_fn(
input: ParseStream,
outer_attrs: Vec<Attribute>,
mut attrs: Vec<Attribute>,
vis: Visibility,
sig: Signature,
) -> Result<ItemFn> {
let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
attr::parsing::parse_inner(&content, &mut attrs)?;
let stmts = content.call(Block::parse_within)?;

Ok(ItemFn {
attrs: private::attrs(outer_attrs, inner_attrs),
attrs,
vis,
sig,
block: Box::new(Block { brace_token, stmts }),
Expand Down Expand Up @@ -1669,15 +1669,15 @@ pub mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ItemMod {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let mut attrs = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
let mod_token: Token![mod] = input.parse()?;
let ident: Ident = input.parse()?;

let lookahead = input.lookahead1();
if lookahead.peek(Token![;]) {
Ok(ItemMod {
attrs: outer_attrs,
attrs,
vis,
mod_token,
ident,
Expand All @@ -1687,15 +1687,15 @@ pub mod parsing {
} else if lookahead.peek(token::Brace) {
let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
attr::parsing::parse_inner(&content, &mut attrs)?;

let mut items = Vec::new();
while !content.is_empty() {
items.push(content.parse()?);
}

Ok(ItemMod {
attrs: private::attrs(outer_attrs, inner_attrs),
attrs,
vis,
mod_token,
ident,
Expand All @@ -1711,19 +1711,19 @@ pub mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ItemForeignMod {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let mut attrs = input.call(Attribute::parse_outer)?;
let abi: Abi = input.parse()?;

let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
attr::parsing::parse_inner(&content, &mut attrs)?;
let mut items = Vec::new();
while !content.is_empty() {
items.push(content.parse()?);
}

Ok(ItemForeignMod {
attrs: private::attrs(outer_attrs, inner_attrs),
attrs,
abi,
brace_token,
items,
Expand Down Expand Up @@ -2130,7 +2130,7 @@ pub mod parsing {

fn parse_rest_of_trait(
input: ParseStream,
outer_attrs: Vec<Attribute>,
mut attrs: Vec<Attribute>,
vis: Visibility,
unsafety: Option<Token![unsafe]>,
auto_token: Option<Token![auto]>,
Expand Down Expand Up @@ -2158,14 +2158,14 @@ pub mod parsing {

let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
attr::parsing::parse_inner(&content, &mut attrs)?;
let mut items = Vec::new();
while !content.is_empty() {
items.push(content.parse()?);
}

Ok(ItemTrait {
attrs: private::attrs(outer_attrs, inner_attrs),
attrs,
vis,
unsafety,
auto_token,
Expand Down Expand Up @@ -2330,25 +2330,25 @@ pub mod parsing {
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for TraitItemMethod {
fn parse(input: ParseStream) -> Result<Self> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let mut attrs = input.call(Attribute::parse_outer)?;
let sig: Signature = input.parse()?;

let lookahead = input.lookahead1();
let (brace_token, inner_attrs, stmts, semi_token) = if lookahead.peek(token::Brace) {
let (brace_token, stmts, semi_token) = if lookahead.peek(token::Brace) {
let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
attr::parsing::parse_inner(&content, &mut attrs)?;
let stmts = content.call(Block::parse_within)?;
(Some(brace_token), inner_attrs, stmts, None)
(Some(brace_token), stmts, None)
} else if lookahead.peek(Token![;]) {
let semi_token: Token![;] = input.parse()?;
(None, Vec::new(), Vec::new(), Some(semi_token))
(None, Vec::new(), Some(semi_token))
} else {
return Err(lookahead.error());
};

Ok(TraitItemMethod {
attrs: private::attrs(outer_attrs, inner_attrs),
attrs,
sig,
default: brace_token.map(|brace_token| Block { brace_token, stmts }),
semi_token,
Expand Down Expand Up @@ -2455,7 +2455,7 @@ pub mod parsing {
}

fn parse_impl(input: ParseStream, allow_const_impl: bool) -> Result<Option<ItemImpl>> {
let outer_attrs = input.call(Attribute::parse_outer)?;
let mut attrs = input.call(Attribute::parse_outer)?;
let defaultness: Option<Token![default]> = input.parse()?;
let unsafety: Option<Token![unsafe]> = input.parse()?;
let impl_token: Token![impl] = input.parse()?;
Expand Down Expand Up @@ -2525,7 +2525,7 @@ pub mod parsing {

let content;
let brace_token = braced!(content in input);
let inner_attrs = content.call(Attribute::parse_inner)?;
attr::parsing::parse_inner(&content, &mut attrs)?;

let mut items = Vec::new();
while !content.is_empty() {
Expand All @@ -2536,7 +2536,7 @@ pub mod parsing {
Ok(None)
} else {
Ok(Some(ItemImpl {
attrs: private::attrs(outer_attrs, inner_attrs),
attrs,
defaultness,
unsafety,
impl_token,
Expand Down