diff options
Diffstat (limited to 'syn-mid/src')
-rw-r--r-- | syn-mid/src/arg.rs | 99 | ||||
-rw-r--r-- | syn-mid/src/lib.rs | 190 | ||||
-rw-r--r-- | syn-mid/src/macros.rs | 107 | ||||
-rw-r--r-- | syn-mid/src/pat.rs | 413 | ||||
-rw-r--r-- | syn-mid/src/path.rs | 50 |
5 files changed, 0 insertions, 859 deletions
diff --git a/syn-mid/src/arg.rs b/syn-mid/src/arg.rs deleted file mode 100644 index 593a1ac..0000000 --- a/syn-mid/src/arg.rs +++ /dev/null @@ -1,99 +0,0 @@ -use syn::{Attribute, Lifetime, Token}; - -use super::PatType; - -ast_enum_of_structs! { - /// An argument in a function signature: the `n: usize` in `fn f(n: usize)`. - pub enum FnArg { - /// The `self` argument of an associated method, whether taken by value - /// or by reference. - Receiver(Receiver), - - /// A function argument accepted by pattern and type. - Typed(PatType), - } -} - -ast_struct! { - /// The `self` argument of an associated method, whether taken by value - /// or by reference. - pub struct Receiver { - pub attrs: Vec<Attribute>, - pub reference: Option<(Token![&], Option<Lifetime>)>, - pub mutability: Option<Token![mut]>, - pub self_token: Token![self], - } -} - -mod parsing { - use syn::{ - parse::{discouraged::Speculative, Parse, ParseStream, Result}, - Attribute, Token, - }; - - use super::{FnArg, PatType, Receiver}; - - impl Parse for FnArg { - fn parse(input: ParseStream<'_>) -> Result<Self> { - let attrs = input.call(Attribute::parse_outer)?; - - let ahead = input.fork(); - if let Ok(mut receiver) = ahead.parse::<Receiver>() { - if !ahead.peek(Token![:]) { - input.advance_to(&ahead); - receiver.attrs = attrs; - return Ok(FnArg::Receiver(receiver)); - } - } - - let mut typed = input.call(fn_arg_typed)?; - typed.attrs = attrs; - Ok(FnArg::Typed(typed)) - } - } - - impl Parse for Receiver { - fn parse(input: ParseStream<'_>) -> Result<Self> { - Ok(Self { - attrs: Vec::new(), - reference: { - if input.peek(Token![&]) { - Some((input.parse()?, input.parse()?)) - } else { - None - } - }, - mutability: input.parse()?, - self_token: input.parse()?, - }) - } - } - - fn fn_arg_typed(input: ParseStream<'_>) -> Result<PatType> { - Ok(PatType { - attrs: Vec::new(), - pat: input.parse()?, - colon_token: input.parse()?, - ty: Box::new(input.parse()?), - }) - } -} - -mod printing { - use proc_macro2::TokenStream; - use quote::{ToTokens, TokenStreamExt}; - - use super::Receiver; - - impl ToTokens for Receiver { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append_all(&self.attrs); - if let Some((ampersand, lifetime)) = &self.reference { - ampersand.to_tokens(tokens); - lifetime.to_tokens(tokens); - } - self.mutability.to_tokens(tokens); - self.self_token.to_tokens(tokens); - } - } -} diff --git a/syn-mid/src/lib.rs b/syn-mid/src/lib.rs deleted file mode 100644 index 69bdec9..0000000 --- a/syn-mid/src/lib.rs +++ /dev/null @@ -1,190 +0,0 @@ -//! Providing the features between "full" and "derive" of syn. -//! -//! This crate provides the following two unique data structures. -//! -//! * [`syn_mid::ItemFn`] -- A function whose body is not parsed. -//! -//! ```text -//! fn process(n: usize) -> Result<()> { ... } -//! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ ^ -//! ``` -//! -//! * [`syn_mid::Block`] -- A block whose body is not parsed. -//! -//! ```text -//! { ... } -//! ^ ^ -//! ``` -//! -//! Other data structures are the same as data structures of [syn]. These are defined in this crate -//! because they cannot be used in [syn] without "full" feature. -//! -//! ## Optional features -//! -//! syn-mid in the default features aims to provide the features between "full" -//! and "derive" of [syn]. -//! -//! * **`clone-impls`** — Clone impls for all syntax tree types. -//! -//! [`syn_mid::ItemFn`]: struct.ItemFn.html -//! [`syn_mid::Block`]: struct.Block.html -//! [syn]: https://github.com/dtolnay/syn -//! - -#![doc(html_root_url = "https://docs.rs/syn-mid/0.4.0")] -#![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] -#![warn(unsafe_code)] -#![warn(rust_2018_idioms, unreachable_pub)] -#![warn(single_use_lifetimes)] -#![warn(clippy::all, clippy::pedantic)] -#![allow( - clippy::eval_order_dependence, - clippy::large_enum_variant, - clippy::module_name_repetitions, - clippy::use_self -)] - -// Many of the code contained in this crate are copies from https://github.com/dtolnay/syn. - -#[macro_use] -mod macros; - -mod arg; -mod pat; -mod path; - -pub use self::arg::*; -pub use self::pat::*; - -use proc_macro2::TokenStream; -use syn::{ - punctuated::Punctuated, token, Abi, Attribute, Generics, Ident, ReturnType, Token, Visibility, -}; - -ast_struct! { - /// A braced block containing Rust statements. - pub struct Block { - pub brace_token: token::Brace, - /// Statements in a block - pub stmts: TokenStream, - } -} - -ast_struct! { - /// A free-standing function: `fn process(n: usize) -> Result<()> { ... - /// }`. - pub struct ItemFn { - pub attrs: Vec<Attribute>, - pub vis: Visibility, - pub constness: Option<Token![const]>, - pub asyncness: Option<Token![async]>, - pub unsafety: Option<Token![unsafe]>, - pub abi: Option<Abi>, - pub fn_token: Token![fn], - pub ident: Ident, - pub generics: Generics, - pub paren_token: token::Paren, - pub inputs: Punctuated<FnArg, Token![,]>, - pub output: ReturnType, - pub block: Block, - } -} - -mod parsing { - use syn::{ - braced, parenthesized, - parse::{Parse, ParseStream, Result}, - Abi, Attribute, Generics, Ident, ReturnType, Token, Visibility, WhereClause, - }; - - use super::{Block, FnArg, ItemFn}; - - impl Parse for Block { - fn parse(input: ParseStream<'_>) -> Result<Self> { - let content; - Ok(Self { - brace_token: braced!(content in input), - stmts: content.parse()?, - }) - } - } - - impl Parse for ItemFn { - fn parse(input: ParseStream<'_>) -> Result<Self> { - let attrs = input.call(Attribute::parse_outer)?; - let vis: Visibility = input.parse()?; - let constness: Option<Token![const]> = input.parse()?; - let asyncness: Option<Token![async]> = input.parse()?; - let unsafety: Option<Token![unsafe]> = input.parse()?; - let abi: Option<Abi> = input.parse()?; - let fn_token: Token![fn] = input.parse()?; - let ident: Ident = input.parse()?; - let generics: Generics = input.parse()?; - - let content; - let paren_token = parenthesized!(content in input); - let inputs = content.parse_terminated(FnArg::parse)?; - - let output: ReturnType = input.parse()?; - let where_clause: Option<WhereClause> = input.parse()?; - - let block = input.parse()?; - - Ok(Self { - attrs, - vis, - constness, - asyncness, - unsafety, - abi, - fn_token, - ident, - generics: Generics { - where_clause, - ..generics - }, - paren_token, - inputs, - output, - block, - }) - } - } -} - -mod printing { - use proc_macro2::TokenStream; - use quote::{ToTokens, TokenStreamExt}; - - use super::{Block, ItemFn}; - - impl ToTokens for Block { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.brace_token.surround(tokens, |tokens| { - tokens.append_all(self.stmts.clone()); - }); - } - } - - impl ToTokens for ItemFn { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append_all(&self.attrs); - self.vis.to_tokens(tokens); - self.constness.to_tokens(tokens); - self.asyncness.to_tokens(tokens); - self.unsafety.to_tokens(tokens); - self.abi.to_tokens(tokens); - self.fn_token.to_tokens(tokens); - self.ident.to_tokens(tokens); - self.generics.to_tokens(tokens); - self.paren_token.surround(tokens, |tokens| { - self.inputs.to_tokens(tokens); - }); - self.output.to_tokens(tokens); - self.generics.where_clause.to_tokens(tokens); - self.block.brace_token.surround(tokens, |tokens| { - tokens.append_all(self.block.stmts.clone()); - }); - } - } -} diff --git a/syn-mid/src/macros.rs b/syn-mid/src/macros.rs deleted file mode 100644 index 87be7b4..0000000 --- a/syn-mid/src/macros.rs +++ /dev/null @@ -1,107 +0,0 @@ -macro_rules! ast_struct { - ( - [$($attrs_pub:tt)*] - struct $name:ident $($rest:tt)* - ) => { - #[cfg_attr(feature = "clone-impls", derive(Clone))] - $($attrs_pub)* struct $name $($rest)* - }; - - ($($t:tt)*) => { - strip_attrs_pub!(ast_struct!($($t)*)); - }; -} - -macro_rules! ast_enum { - ( - [$($attrs_pub:tt)*] - enum $name:ident $($rest:tt)* - ) => ( - #[cfg_attr(feature = "clone-impls", derive(Clone))] - $($attrs_pub)* enum $name $($rest)* - ); - - ($($t:tt)*) => { - strip_attrs_pub!(ast_enum!($($t)*)); - }; -} - -macro_rules! ast_enum_of_structs { - ( - $(#[$enum_attr:meta])* - $pub:ident $enum:ident $name:ident $body:tt - ) => { - ast_enum!($(#[$enum_attr])* $pub $enum $name $body); - ast_enum_of_structs_impl!($pub $enum $name $body); - }; -} - -macro_rules! ast_enum_of_structs_impl { - ( - $pub:ident $enum:ident $name:ident { - $( - $(#[$variant_attr:meta])* - $variant:ident $( ($member:ident) )*, - )* - } - ) => { - check_keyword_matches!(pub $pub); - check_keyword_matches!(enum $enum); - - $( - $( - impl From<$member> for $name { - fn from(e: $member) -> $name { - $name::$variant(e) - } - } - )* - )* - - generate_to_tokens! { - () - tokens - $name { $($variant $($member)*,)* } - } - }; -} - -macro_rules! generate_to_tokens { - (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident, $($next:tt)*}) => { - generate_to_tokens!( - ($($arms)* $name::$variant => {}) - $tokens $name { $($next)* } - ); - }; - - (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident $member:ident, $($next:tt)*}) => { - generate_to_tokens!( - ($($arms)* $name::$variant(_e) => quote::ToTokens::to_tokens(_e, $tokens),) - $tokens $name { $($next)* } - ); - }; - - (($($arms:tt)*) $tokens:ident $name:ident {}) => { - impl quote::ToTokens for $name { - fn to_tokens(&self, $tokens: &mut proc_macro2::TokenStream) { - match self { - $($arms)* - } - } - } - }; -} - -macro_rules! strip_attrs_pub { - ($mac:ident!($(#[$m:meta])* $pub:ident $($t:tt)*)) => { - check_keyword_matches!(pub $pub); - - $mac!([$(#[$m])* $pub] $($t)*); - }; -} - -macro_rules! check_keyword_matches { - (struct struct) => {}; - (enum enum) => {}; - (pub pub) => {}; -} diff --git a/syn-mid/src/pat.rs b/syn-mid/src/pat.rs deleted file mode 100644 index 8f95381..0000000 --- a/syn-mid/src/pat.rs +++ /dev/null @@ -1,413 +0,0 @@ -use syn::{punctuated::Punctuated, token, Attribute, Ident, Member, Path, Token, Type}; - -ast_enum_of_structs! { - /// A pattern in a local binding, function signature, match expression, or - /// various other places. - /// - /// # Syntax tree enum - /// - /// This type is a [syntax tree enum]. - /// - /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums - pub enum Pat { - /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`. - Ident(PatIdent), - - /// A path pattern like `Color::Red`. - Path(PatPath), - - /// A reference pattern: `&mut var`. - Reference(PatReference), - - /// A struct or struct variant pattern: `Variant { x, y, .. }`. - Struct(PatStruct), - - /// A tuple pattern: `(a, b)`. - Tuple(PatTuple), - - /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`. - TupleStruct(PatTupleStruct), - - /// A type ascription pattern: `foo: f64`. - Type(PatType), - - /// A pattern that matches any value: `_`. - Wild(PatWild), - - #[doc(hidden)] - __Nonexhaustive, - } -} - -ast_struct! { - /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`. - pub struct PatIdent { - pub attrs: Vec<Attribute>, - pub by_ref: Option<Token![ref]>, - pub mutability: Option<Token![mut]>, - pub ident: Ident, - } -} - -ast_struct! { - /// A path pattern like `Color::Red`. - pub struct PatPath { - pub attrs: Vec<Attribute>, - pub path: Path, - } -} - -ast_struct! { - /// A reference pattern: `&mut var`. - pub struct PatReference { - pub attrs: Vec<Attribute>, - pub and_token: Token![&], - pub mutability: Option<Token![mut]>, - pub pat: Box<Pat>, - } -} - -ast_struct! { - /// A struct or struct variant pattern: `Variant { x, y, .. }`. - pub struct PatStruct { - pub attrs: Vec<Attribute>, - pub path: Path, - pub brace_token: token::Brace, - pub fields: Punctuated<FieldPat, Token![,]>, - pub dot2_token: Option<Token![..]>, - } -} - -ast_struct! { - /// A tuple pattern: `(a, b)`. - pub struct PatTuple { - pub attrs: Vec<Attribute>, - pub paren_token: token::Paren, - pub elems: Punctuated<Pat, Token![,]>, - } -} - -ast_struct! { - /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`. - pub struct PatTupleStruct { - pub attrs: Vec<Attribute>, - pub path: Path, - pub pat: PatTuple, - } -} - -ast_struct! { - /// A type ascription pattern: `foo: f64`. - pub struct PatType { - pub attrs: Vec<Attribute>, - pub pat: Box<Pat>, - pub colon_token: Token![:], - pub ty: Box<Type>, - } -} - -ast_struct! { - /// A pattern that matches any value: `_`. - pub struct PatWild { - pub attrs: Vec<Attribute>, - pub underscore_token: Token![_], - } -} - -ast_struct! { - /// A single field in a struct pattern. - /// - /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated - /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token. - pub struct FieldPat { - pub attrs: Vec<Attribute>, - pub member: Member, - pub colon_token: Option<Token![:]>, - pub pat: Box<Pat>, - } -} - -mod parsing { - use syn::{ - braced, - ext::IdentExt, - parenthesized, - parse::{Parse, ParseStream, Result}, - punctuated::Punctuated, - token, Ident, Member, Path, Token, - }; - - use crate::path; - - use super::{ - FieldPat, Pat, PatIdent, PatPath, PatReference, PatStruct, PatTuple, PatTupleStruct, - PatWild, - }; - - impl Parse for Pat { - fn parse(input: ParseStream<'_>) -> Result<Self> { - let lookahead = input.lookahead1(); - if lookahead.peek(Ident) - && ({ - input.peek2(Token![::]) - || input.peek2(token::Brace) - || input.peek2(token::Paren) - }) - || input.peek(Token![self]) && input.peek2(Token![::]) - || lookahead.peek(Token![::]) - || lookahead.peek(Token![<]) - || input.peek(Token![Self]) - || input.peek(Token![super]) - || input.peek(Token![extern]) - || input.peek(Token![crate]) - { - pat_path_or_struct(input) - } else if lookahead.peek(Token![_]) { - input.call(pat_wild).map(Pat::Wild) - } else if lookahead.peek(Token![ref]) - || lookahead.peek(Token![mut]) - || input.peek(Token![self]) - || input.peek(Ident) - { - input.call(pat_ident).map(Pat::Ident) - } else if lookahead.peek(Token![&]) { - input.call(pat_reference).map(Pat::Reference) - } else if lookahead.peek(token::Paren) { - input.call(pat_tuple).map(Pat::Tuple) - } else { - Err(lookahead.error()) - } - } - } - - fn pat_path_or_struct(input: ParseStream<'_>) -> Result<Pat> { - let path = path::parse_path(input)?; - - if input.peek(token::Brace) { - pat_struct(input, path).map(Pat::Struct) - } else if input.peek(token::Paren) { - pat_tuple_struct(input, path).map(Pat::TupleStruct) - } else { - Ok(Pat::Path(PatPath { - attrs: Vec::new(), - path, - })) - } - } - - fn pat_wild(input: ParseStream<'_>) -> Result<PatWild> { - Ok(PatWild { - attrs: Vec::new(), - underscore_token: input.parse()?, - }) - } - - fn pat_ident(input: ParseStream<'_>) -> Result<PatIdent> { - Ok(PatIdent { - attrs: Vec::new(), - by_ref: input.parse()?, - mutability: input.parse()?, - ident: input.call(Ident::parse_any)?, - }) - } - - fn pat_tuple_struct(input: ParseStream<'_>, path: Path) -> Result<PatTupleStruct> { - Ok(PatTupleStruct { - attrs: Vec::new(), - path, - pat: input.call(pat_tuple)?, - }) - } - - fn pat_struct(input: ParseStream<'_>, path: Path) -> Result<PatStruct> { - let content; - let brace_token = braced!(content in input); - - let mut fields = Punctuated::new(); - while !content.is_empty() && !content.peek(Token![..]) { - let value = content.call(field_pat)?; - fields.push_value(value); - if !content.peek(Token![,]) { - break; - } - let punct: Token![,] = content.parse()?; - fields.push_punct(punct); - } - - let dot2_token = if fields.empty_or_trailing() && content.peek(Token![..]) { - Some(content.parse()?) - } else { - None - }; - - Ok(PatStruct { - attrs: Vec::new(), - path, - brace_token, - fields, - dot2_token, - }) - } - - fn field_pat(input: ParseStream<'_>) -> Result<FieldPat> { - let boxed: Option<Token![box]> = input.parse()?; - let by_ref: Option<Token![ref]> = input.parse()?; - let mutability: Option<Token![mut]> = input.parse()?; - let member: Member = input.parse()?; - - if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:]) - || is_unnamed(&member) - { - return Ok(FieldPat { - attrs: Vec::new(), - member, - colon_token: input.parse()?, - pat: input.parse()?, - }); - } - - let ident = match member { - Member::Named(ident) => ident, - Member::Unnamed(_) => unreachable!(), - }; - - let pat = Pat::Ident(PatIdent { - attrs: Vec::new(), - by_ref, - mutability, - ident: ident.clone(), - }); - - Ok(FieldPat { - member: Member::Named(ident), - pat: Box::new(pat), - attrs: Vec::new(), - colon_token: None, - }) - } - - fn pat_tuple(input: ParseStream<'_>) -> Result<PatTuple> { - let content; - let paren_token = parenthesized!(content in input); - - let mut elems = Punctuated::new(); - while !content.is_empty() { - let value: Pat = content.parse()?; - elems.push_value(value); - if content.is_empty() { - break; - } - let punct = content.parse()?; - elems.push_punct(punct); - } - - Ok(PatTuple { - attrs: Vec::new(), - paren_token, - elems, - }) - } - - fn pat_reference(input: ParseStream<'_>) -> Result<PatReference> { - Ok(PatReference { - attrs: Vec::new(), - and_token: input.parse()?, - mutability: input.parse()?, - pat: input.parse()?, - }) - } - - fn is_unnamed(member: &Member) -> bool { - match member { - Member::Named(_) => false, - Member::Unnamed(_) => true, - } - } -} - -mod printing { - use proc_macro2::TokenStream; - use quote::{ToTokens, TokenStreamExt}; - use syn::Token; - - use super::{ - FieldPat, PatIdent, PatPath, PatReference, PatStruct, PatTuple, PatTupleStruct, PatType, - PatWild, - }; - - impl ToTokens for PatWild { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.underscore_token.to_tokens(tokens); - } - } - - impl ToTokens for PatIdent { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.by_ref.to_tokens(tokens); - self.mutability.to_tokens(tokens); - self.ident.to_tokens(tokens); - } - } - - impl ToTokens for PatStruct { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.path.to_tokens(tokens); - self.brace_token.surround(tokens, |tokens| { - self.fields.to_tokens(tokens); - // NOTE: We need a comma before the dot2 token if it is present. - if !self.fields.empty_or_trailing() && self.dot2_token.is_some() { - <Token![,]>::default().to_tokens(tokens); - } - self.dot2_token.to_tokens(tokens); - }); - } - } - - impl ToTokens for PatTupleStruct { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.path.to_tokens(tokens); - self.pat.to_tokens(tokens); - } - } - - impl ToTokens for PatType { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append_all(&self.attrs); - self.pat.to_tokens(tokens); - self.colon_token.to_tokens(tokens); - self.ty.to_tokens(tokens); - } - } - - impl ToTokens for PatPath { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.path.to_tokens(tokens) - } - } - - impl ToTokens for PatTuple { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.paren_token.surround(tokens, |tokens| { - self.elems.to_tokens(tokens); - }); - } - } - - impl ToTokens for PatReference { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.and_token.to_tokens(tokens); - self.mutability.to_tokens(tokens); - self.pat.to_tokens(tokens); - } - } - - impl ToTokens for FieldPat { - fn to_tokens(&self, tokens: &mut TokenStream) { - if let Some(colon_token) = &self.colon_token { - self.member.to_tokens(tokens); - colon_token.to_tokens(tokens); - } - self.pat.to_tokens(tokens); - } - } -} diff --git a/syn-mid/src/path.rs b/syn-mid/src/path.rs deleted file mode 100644 index 8093b53..0000000 --- a/syn-mid/src/path.rs +++ /dev/null @@ -1,50 +0,0 @@ -use syn::{ - ext::IdentExt, - parse::{ParseStream, Result}, - punctuated::Punctuated, - Ident, Path, PathArguments, PathSegment, Token, -}; - -fn parse_path_segment(input: ParseStream<'_>) -> Result<PathSegment> { - if input.peek(Token![super]) - || input.peek(Token![self]) - || input.peek(Token![crate]) - || input.peek(Token![extern]) - { - let ident = input.call(Ident::parse_any)?; - return Ok(PathSegment::from(ident)); - } - - let ident = if input.peek(Token![Self]) { - input.call(Ident::parse_any)? - } else { - input.parse()? - }; - - if input.peek(Token![::]) && input.peek3(Token![<]) { - Ok(PathSegment { - ident, - arguments: PathArguments::AngleBracketed(input.parse()?), - }) - } else { - Ok(PathSegment::from(ident)) - } -} - -pub(crate) fn parse_path(input: ParseStream<'_>) -> Result<Path> { - Ok(Path { - leading_colon: input.parse()?, - segments: { - let mut segments = Punctuated::new(); - let value = parse_path_segment(input)?; - segments.push_value(value); - while input.peek(Token![::]) { - let punct: Token![::] = input.parse()?; - segments.push_punct(punct); - let value = parse_path_segment(input)?; - segments.push_value(value); - } - segments - }, - }) -} |