Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
36
third-party/vendor/pmutil/src/comment.rs
vendored
Normal file
36
third-party/vendor/pmutil/src/comment.rs
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//!
|
||||
//!
|
||||
use super::SpanExt;
|
||||
use proc_macro2::Span;
|
||||
use syn::punctuated::Pair;
|
||||
use syn::*;
|
||||
|
||||
/// Creates a comment from `s`.
|
||||
pub fn comment<S>(s: S) -> Attribute
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
let span = Span::call_site();
|
||||
|
||||
Attribute {
|
||||
style: AttrStyle::Outer,
|
||||
bracket_token: span.as_token(),
|
||||
pound_token: span.as_token(),
|
||||
meta: Meta::NameValue(MetaNameValue {
|
||||
path: Path {
|
||||
leading_colon: None,
|
||||
segments: vec![Pair::End(PathSegment {
|
||||
ident: Ident::new("doc", span),
|
||||
arguments: Default::default(),
|
||||
})]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
},
|
||||
eq_token: span.as_token(),
|
||||
value: Expr::Lit(ExprLit {
|
||||
attrs: Default::default(),
|
||||
lit: Lit::Str(LitStr::new(s.as_ref(), span)),
|
||||
}),
|
||||
}),
|
||||
}
|
||||
}
|
||||
62
third-party/vendor/pmutil/src/lib.rs
vendored
Normal file
62
third-party/vendor/pmutil/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
//! Utils for implementing proc-macro. Works on stable.
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
|
||||
#![recursion_limit = "128"]
|
||||
|
||||
extern crate proc_macro;
|
||||
pub use proc_macro2;
|
||||
pub use quote;
|
||||
pub use syn;
|
||||
|
||||
pub use self::span_ext::SpanExt;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::ToTokens;
|
||||
pub use spanned_quote::Quote;
|
||||
use syn::Ident;
|
||||
|
||||
pub mod comment;
|
||||
pub mod prelude;
|
||||
pub mod respan;
|
||||
mod span_ext;
|
||||
pub mod spanned_quote;
|
||||
pub mod synom_ext;
|
||||
|
||||
/// Extension trait for [syn::Ident][].
|
||||
///
|
||||
///
|
||||
///[syn::Ident]:../syn/struct.Ident.html
|
||||
pub trait IdentExt {
|
||||
/// Creates a new ident with same span by applying `map` to `self`.
|
||||
fn new_ident_with<F, S>(&self, map: F) -> Ident
|
||||
where
|
||||
F: for<'a> FnOnce(&'a str) -> S,
|
||||
S: AsRef<str>;
|
||||
}
|
||||
|
||||
impl IdentExt for Ident {
|
||||
/// Creates a new ident with same span by applying `map` to `self`.
|
||||
fn new_ident_with<F, S>(&self, map: F) -> Ident
|
||||
where
|
||||
F: for<'a> FnOnce(&'a str) -> S,
|
||||
S: AsRef<str>,
|
||||
{
|
||||
Ident::new(map(&format!("{self}")).as_ref(), self.span())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToTokensExt: ToTokens {
|
||||
fn dump(&self) -> TokenStream {
|
||||
let mut tmp = TokenStream::new();
|
||||
self.to_tokens(&mut tmp);
|
||||
tmp
|
||||
}
|
||||
|
||||
/// Usage: `Quote::new(body.first_last())`
|
||||
fn first_last(&self) -> respan::FirstLast {
|
||||
respan::FirstLast::from_tokens(&self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToTokens> ToTokensExt for T {}
|
||||
6
third-party/vendor/pmutil/src/prelude.rs
vendored
Normal file
6
third-party/vendor/pmutil/src/prelude.rs
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
//! Prelude for convenience.
|
||||
|
||||
pub use super::comment::comment;
|
||||
pub use super::spanned_quote::Quote;
|
||||
pub use super::{IdentExt, SpanExt, ToTokensExt};
|
||||
pub use crate::{q, smart_quote};
|
||||
76
third-party/vendor/pmutil/src/respan.rs
vendored
Normal file
76
third-party/vendor/pmutil/src/respan.rs
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
//! Span support for quasi-quotting.
|
||||
|
||||
use proc_macro2::{Span, TokenStream, TokenTree};
|
||||
use quote::ToTokens;
|
||||
use std::cell::Cell;
|
||||
|
||||
pub trait Respan {
|
||||
/// Used while quasi quotting.
|
||||
fn next_span(&self) -> Span;
|
||||
|
||||
fn respan(&self, mut tt: TokenTree) -> TokenTree {
|
||||
let span = self.next_span();
|
||||
|
||||
match tt {
|
||||
TokenTree::Group(ref mut tt) => tt.set_span(span),
|
||||
TokenTree::Ident(ref mut tt) => tt.set_span(span),
|
||||
TokenTree::Punct(ref mut tt) => tt.set_span(span),
|
||||
TokenTree::Literal(ref mut tt) => tt.set_span(span),
|
||||
}
|
||||
|
||||
tt
|
||||
}
|
||||
}
|
||||
|
||||
impl Respan for Span {
|
||||
fn next_span(&self) -> Span {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S> Respan for &'a S
|
||||
where
|
||||
S: ?Sized + Respan,
|
||||
{
|
||||
fn next_span(&self) -> Span {
|
||||
<S as Respan>::next_span(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Respan for Box<S>
|
||||
where
|
||||
S: ?Sized + Respan,
|
||||
{
|
||||
fn next_span(&self) -> Span {
|
||||
<S as Respan>::next_span(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FirstLast {
|
||||
first: Cell<Option<Span>>,
|
||||
last: Span,
|
||||
}
|
||||
impl Respan for FirstLast {
|
||||
fn next_span(&self) -> Span {
|
||||
// Default value of Option<_> is None, so Cell<Option<_>>.take() works
|
||||
self.first.take().unwrap_or(self.last)
|
||||
}
|
||||
}
|
||||
|
||||
impl FirstLast {
|
||||
pub fn from_tokens(tokens: &dyn ToTokens) -> Self {
|
||||
let mut spans = TokenStream::new();
|
||||
tokens.to_tokens(&mut spans);
|
||||
let good_tokens = spans.into_iter().collect::<Vec<_>>();
|
||||
let first_span = good_tokens
|
||||
.first()
|
||||
.map(|t| t.span())
|
||||
.unwrap_or(Span::call_site());
|
||||
let last = good_tokens.last().map(|t| t.span()).unwrap_or(first_span);
|
||||
FirstLast {
|
||||
first: Cell::new(Some(first_span)),
|
||||
last,
|
||||
}
|
||||
}
|
||||
}
|
||||
32
third-party/vendor/pmutil/src/span_ext.rs
vendored
Normal file
32
third-party/vendor/pmutil/src/span_ext.rs
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
use crate::synom_ext::FromSpan;
|
||||
use proc_macro2::Span;
|
||||
|
||||
/// Extension trait for [Span][] and [syn::Span][].
|
||||
///
|
||||
///
|
||||
///[Span]:../proc_macro2/struct.Span.html
|
||||
///[syn::Span]:../syn/struct.Span.html
|
||||
pub trait SpanExt: Copy {
|
||||
fn new_ident<S>(self, s: S) -> syn::Ident
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
syn::Ident::new(s.as_ref(), self.into_pm2_span())
|
||||
}
|
||||
|
||||
/// Creates `Token` from `self`.
|
||||
fn as_token<Token>(self) -> Token
|
||||
where
|
||||
Token: FromSpan,
|
||||
{
|
||||
Token::from_span(self.into_pm2_span())
|
||||
}
|
||||
|
||||
fn into_pm2_span(self) -> Span;
|
||||
}
|
||||
|
||||
impl SpanExt for Span {
|
||||
fn into_pm2_span(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
283
third-party/vendor/pmutil/src/spanned_quote.rs
vendored
Normal file
283
third-party/vendor/pmutil/src/spanned_quote.rs
vendored
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
//! Span-aware quasi quotting built on top of `quote` crate.
|
||||
//!
|
||||
|
||||
mod buffer;
|
||||
pub use self::buffer::{Location, Quote};
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! quoter_location {
|
||||
() => {{
|
||||
$crate::spanned_quote::Location {
|
||||
line: line!(),
|
||||
col: column!(),
|
||||
file_name: file!(),
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
// ----- Start of variable handling macros.
|
||||
|
||||
/// Usage: __sq_handle_vars! { a, b: expression(), c, };
|
||||
///
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! handle_vars_for_quote {
|
||||
(
|
||||
@NORMALIZED {
|
||||
$(
|
||||
$name:ident: $value:expr,
|
||||
)*
|
||||
},
|
||||
) => {
|
||||
$crate::declare_vars_for_quote!(
|
||||
$($name: $value,)*
|
||||
);
|
||||
};
|
||||
|
||||
(
|
||||
@NORMALIZED {
|
||||
$($norm:tt)*
|
||||
},
|
||||
$name:ident,
|
||||
$($rest:tt)*
|
||||
) => {
|
||||
$crate::handle_vars_for_quote!(
|
||||
@NORMALIZED {
|
||||
$($norm)*
|
||||
$name: $name,
|
||||
},
|
||||
$($rest)*
|
||||
)
|
||||
};
|
||||
|
||||
(
|
||||
@NORMALIZED {
|
||||
$($norm:tt)*
|
||||
},
|
||||
$name:ident
|
||||
) => {
|
||||
$crate::handle_vars_for_quote!(
|
||||
@NORMALIZED {
|
||||
$($norm)*
|
||||
$name: $name,
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
(
|
||||
@NORMALIZED {
|
||||
$($norm:tt)*
|
||||
},
|
||||
$name:ident: $value:expr,
|
||||
$($rest:tt)*
|
||||
) => {
|
||||
$crate::handle_vars_for_quote!(
|
||||
@NORMALIZED {
|
||||
$($norm)*
|
||||
$name: $value,
|
||||
},
|
||||
$($rest)*
|
||||
)
|
||||
};
|
||||
|
||||
(
|
||||
@NORMALIZED {
|
||||
$($norm:tt)*
|
||||
},
|
||||
$name:ident: $value:expr
|
||||
) => {
|
||||
$crate::handle_vars_for_quote!(
|
||||
@NORMALIZED {
|
||||
$($norm)*
|
||||
$name: $value,
|
||||
},
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// This macro handles `Vars`, and creates a new hidden macro used inside quasi-quotting.
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! declare_vars_for_quote {
|
||||
(
|
||||
$(
|
||||
$name:ident: $val:expr,
|
||||
)*
|
||||
) => {
|
||||
$(
|
||||
#[allow(non_snake_case)]
|
||||
let $name = $val;
|
||||
)*
|
||||
|
||||
// This macro quotes only one token at once.
|
||||
macro_rules! __sq_push_token_custom {
|
||||
$(
|
||||
($tokens:expr, $name) => {
|
||||
$tokens.push_tokens(&$name);
|
||||
};
|
||||
)*
|
||||
// default (stringify + parse)
|
||||
($tokens:expr, $t:tt) => {
|
||||
$tokens.push_parsed(stringify!($t));
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// ----- End of variable handling macros.
|
||||
|
||||
/// This macro assumes that `Vars` is already handled.
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __sq_quote_tokens_to {
|
||||
// Done.
|
||||
($tokens:expr,) => {{}};
|
||||
|
||||
($tokens:expr, ( $($inner:tt)* ) $($rest:tt)*) => {{
|
||||
$tokens.push_group(::proc_macro2::Delimiter::Parenthesis, $crate::__sq_quote_closure! {
|
||||
$($inner)*
|
||||
});
|
||||
$crate::__sq_quote_tokens_to!($tokens, $($rest)*);
|
||||
}};
|
||||
|
||||
|
||||
($tokens:expr, { $($inner:tt)* } $($rest:tt)*) => {{
|
||||
$tokens.push_group(::proc_macro2::Delimiter::Brace, $crate::__sq_quote_closure! {
|
||||
$($inner)*
|
||||
});
|
||||
$crate::__sq_quote_tokens_to!($tokens, $($rest)*);
|
||||
}};
|
||||
|
||||
($tokens:expr, [ $($inner:tt)* ] $($rest:tt)*) => {{
|
||||
$tokens.push_group(::proc_macro2::Delimiter::Bracket, $crate::__sq_quote_closure! {
|
||||
$($inner)*
|
||||
});
|
||||
$crate::__sq_quote_tokens_to!($tokens, $($rest)*);
|
||||
}};
|
||||
|
||||
// If we have to quote one token, check if user declared variable.
|
||||
($tokens:expr, $first:tt $($rest:tt)*) => {
|
||||
__sq_push_token_custom!($tokens, $first);
|
||||
|
||||
$crate::__sq_quote_tokens_to!($tokens, $($rest)*);
|
||||
};
|
||||
}
|
||||
|
||||
/// ide-friendly quasi quotting.
|
||||
///
|
||||
///# Syntax
|
||||
///## Vars
|
||||
///Syntax is simillar to field initialization syntax.
|
||||
///
|
||||
///```rust,ignore
|
||||
///Vars {
|
||||
/// a,
|
||||
/// b: expr_b,
|
||||
/// c: fn_c(),
|
||||
/// d,
|
||||
///}
|
||||
/// // is equivalent to
|
||||
///Vars {
|
||||
/// a: a,
|
||||
/// b: expr_b,
|
||||
/// c: fn_c(),
|
||||
/// d: d,
|
||||
///}
|
||||
///
|
||||
///```
|
||||
///
|
||||
///Note that `Vars{}` is required even if there's no variable.
|
||||
///
|
||||
///## Tokens
|
||||
/// As parsers for syntax highligters implement error recovery,
|
||||
/// tokens are wrapped in block or paren like `{ tokens.. }`/ `( tokens.. )`.
|
||||
///
|
||||
///# Example
|
||||
///
|
||||
///```rust,ignore
|
||||
/// smart_quote!(Vars{
|
||||
/// OrigTrait: tr.ident,
|
||||
/// SpecializerTrait: tr.ident.new_ident_with(|tr| format!("{}Specializer", tr)),
|
||||
/// }, {
|
||||
/// impl<T> OrigTrait for T where T: SpecializerTrait {
|
||||
/// }
|
||||
/// })
|
||||
///```
|
||||
///
|
||||
///# Example (no variable)
|
||||
///
|
||||
///```rust,ignore
|
||||
/// smart_quote!(Vars{}, {
|
||||
/// yield ();
|
||||
/// })
|
||||
///```
|
||||
#[macro_export]
|
||||
macro_rules! smart_quote {
|
||||
(
|
||||
Vars{ $($vars:tt)* },
|
||||
{
|
||||
$(
|
||||
$tokens:tt
|
||||
)*
|
||||
}
|
||||
) => {{
|
||||
|_tokens: &mut $crate::Quote| {
|
||||
$crate::handle_vars_for_quote!(@NORMALIZED{}, $($vars)*);
|
||||
|
||||
_tokens.report_loc($crate::quoter_location!());
|
||||
$crate::__sq_quote_tokens_to!(_tokens, $($tokens)*);
|
||||
}
|
||||
}};
|
||||
|
||||
(
|
||||
{
|
||||
$(
|
||||
$tokens:tt
|
||||
)*
|
||||
}
|
||||
) => {{
|
||||
$crate::smart_quote!(Vars {}, { $($tokens)* })
|
||||
}};
|
||||
|
||||
(
|
||||
Vars{ $($vars:tt)* },
|
||||
(
|
||||
$(
|
||||
$tokens:tt
|
||||
)*
|
||||
)
|
||||
) => {
|
||||
$crate::smart_quote!(Vars { $($vars)* }, { $($tokens)* })
|
||||
};
|
||||
|
||||
(
|
||||
(
|
||||
$(
|
||||
$tokens:tt
|
||||
)*
|
||||
)
|
||||
) => {
|
||||
$crate::smart_quote!(Vars {}, { $($tokens)* })
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __sq_quote_closure {
|
||||
( $($tokens:tt)* ) => {{
|
||||
|_tokens: &mut $crate::Quote| {
|
||||
_tokens.report_loc($crate::quoter_location!());
|
||||
$crate::__sq_quote_tokens_to!(_tokens, $($tokens)*);
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// Shortcut for `Quote::new_call_site().quote_with(smart_quote!( $tokens ))`
|
||||
#[macro_export]
|
||||
macro_rules! q {
|
||||
( $($tokens:tt)* ) => {{
|
||||
$crate::Quote::new_call_site().quote_with($crate::smart_quote!( $($tokens)* ))
|
||||
}};
|
||||
}
|
||||
227
third-party/vendor/pmutil/src/spanned_quote/buffer.rs
vendored
Normal file
227
third-party/vendor/pmutil/src/spanned_quote/buffer.rs
vendored
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
use crate::respan::{self, Respan};
|
||||
use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
|
||||
use quote::{ToTokens, TokenStreamExt};
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::fmt::{self, Display, Formatter, Write};
|
||||
use syn::parse::Parse;
|
||||
|
||||
/// Buffer for quasi quotting.
|
||||
pub struct Quote {
|
||||
tts: TokenStream,
|
||||
span: Option<Box<(dyn Respan + 'static)>>,
|
||||
/// Location of smart_quote! invokations.
|
||||
/// Used for error reporting.
|
||||
sources: HashSet<Location>,
|
||||
}
|
||||
|
||||
const INVALID_SPAN_STATE: &str = "Span is in invalid state.
|
||||
Closure provided to push_group should not panic.";
|
||||
|
||||
/// Location of `smart_quote!` macro invocation.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub struct Location {
|
||||
pub file_name: &'static str,
|
||||
pub line: u32,
|
||||
pub col: u32,
|
||||
}
|
||||
|
||||
impl Display for Location {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "{}:{}:{}", self.file_name, self.line, self.col)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Quote {
|
||||
pub fn new<S: Respan + 'static>(span: S) -> Self {
|
||||
Quote {
|
||||
span: Some(Box::new(span)),
|
||||
tts: TokenStream::new(),
|
||||
sources: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Shorthand for
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// Quote::new(Span::call_site())
|
||||
/// ```
|
||||
pub fn new_call_site() -> Self {
|
||||
Self::new(Span::call_site())
|
||||
}
|
||||
|
||||
/// Shorthand for
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// Quote::new(tokens.first_last())
|
||||
/// ```
|
||||
pub fn from_tokens(tokens: &dyn ToTokens) -> Self {
|
||||
Self::new(respan::FirstLast::from_tokens(tokens))
|
||||
}
|
||||
|
||||
/// Shorthand for
|
||||
///
|
||||
///```rust,ignore
|
||||
/// tokens
|
||||
/// .as_ref()
|
||||
/// .map(|tokens| Quote::from_tokens(tokens))
|
||||
/// .unwrap_or_else(|| Quote::new(default_span))
|
||||
///```
|
||||
///
|
||||
pub fn from_tokens_or<T: ToTokens>(tokens: &Option<T>, default_span: Span) -> Self {
|
||||
match *tokens {
|
||||
Some(ref tokens) => Self::from_tokens(tokens),
|
||||
None => Self::new(default_span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Quote {
|
||||
/// Parse tokens as `Node`.
|
||||
/// Panics if parsing failed.
|
||||
pub fn parse<Node>(self) -> Node
|
||||
where
|
||||
Node: Parse,
|
||||
{
|
||||
// TODO: Use span to report error.
|
||||
let Quote { tts, sources, .. } = self;
|
||||
|
||||
let debug_tts = if env::var("DBG_DUMP").is_ok() {
|
||||
Some(tts.clone())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
syn::parse2(tts).unwrap_or_else(|err| {
|
||||
let debug_tts: &dyn Display = match debug_tts {
|
||||
Some(ref tts) => tts,
|
||||
None => {
|
||||
&"To get code failed to parse,
|
||||
please set environment variable `DBG_DUMP` and run in again"
|
||||
}
|
||||
};
|
||||
|
||||
let notes = {
|
||||
let mut b = String::from("Note: quasi quotting was invoked from:\n");
|
||||
for src in &sources {
|
||||
writeln!(b, " {src}").unwrap();
|
||||
}
|
||||
b
|
||||
};
|
||||
|
||||
panic!(
|
||||
"Quote::parse() failed.
|
||||
{notes}
|
||||
Error from syn: {err}
|
||||
>>>>>
|
||||
{debug_tts}
|
||||
<<<<<",
|
||||
notes = notes,
|
||||
err = err,
|
||||
debug_tts = debug_tts
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods for quasi-quotting.
|
||||
impl Quote {
|
||||
#[doc(hidden)]
|
||||
/// Reports location of `smart_quote!` invocation.
|
||||
pub fn report_loc(&mut self, loc: Location) {
|
||||
self.sources.insert(loc);
|
||||
}
|
||||
|
||||
pub fn quote_with<F>(mut self, quote: F) -> Self
|
||||
where
|
||||
F: FnOnce(&mut Self),
|
||||
{
|
||||
(quote)(&mut self);
|
||||
self
|
||||
}
|
||||
|
||||
/// Parse `token` and append it to `self`.
|
||||
pub fn push_parsed(&mut self, token: &str) {
|
||||
let Quote {
|
||||
ref mut span,
|
||||
ref mut tts,
|
||||
..
|
||||
} = *self;
|
||||
|
||||
token
|
||||
.parse::<TokenStream>()
|
||||
.expect("Failed to parse token to quote")
|
||||
.into_iter()
|
||||
.map(|tt| span.as_ref().expect(INVALID_SPAN_STATE).respan(tt))
|
||||
.for_each(|tt| tts.append(tt));
|
||||
}
|
||||
|
||||
/// Append `tt` to `self`.
|
||||
pub fn push_tt(&mut self, tt: TokenTree) {
|
||||
self.tts.append(tt)
|
||||
}
|
||||
|
||||
/// Respan symbol and append it to `self`.
|
||||
pub fn push_sym(&mut self, term: &str) {
|
||||
let span = self.next_span();
|
||||
self.push_tt(TokenTree::Ident(Ident::new(term, span)))
|
||||
}
|
||||
|
||||
fn next_span(&self) -> Span {
|
||||
self.span.as_ref().expect(INVALID_SPAN_STATE).next_span()
|
||||
}
|
||||
|
||||
/// Respan and append `TokenStream::Group`
|
||||
pub fn push_group<F>(&mut self, delim: Delimiter, child: F)
|
||||
where
|
||||
F: FnOnce(&mut Quote),
|
||||
{
|
||||
//TODO: Exception safety
|
||||
let span = self.span.take().expect(INVALID_SPAN_STATE);
|
||||
let mut sub = Quote::new(span);
|
||||
child(&mut sub);
|
||||
self.sources.extend(sub.sources);
|
||||
|
||||
debug_assert!(self.span.is_none());
|
||||
self.span = Some(sub.span.expect(INVALID_SPAN_STATE));
|
||||
|
||||
self.push_tt(TokenTree::Group(Group::new(delim, sub.tts)))
|
||||
}
|
||||
|
||||
/// Appends node into `self` **without respanning**.
|
||||
pub fn push_tokens<T: ?Sized + ToTokens>(&mut self, node: &T) {
|
||||
node.to_tokens(&mut self.tts);
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for Quote {
|
||||
type IntoIter = <TokenStream as IntoIterator>::IntoIter;
|
||||
type Item = <TokenStream as IntoIterator>::Item;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.tts.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Quote> for TokenStream {
|
||||
fn from(quote: Quote) -> Self {
|
||||
quote.tts
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Quote> for proc_macro::TokenStream {
|
||||
fn from(quote: Quote) -> Self {
|
||||
TokenStream::from(quote).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for Quote {
|
||||
fn to_tokens(&self, dst: &mut TokenStream) {
|
||||
self.tts.to_tokens(dst)
|
||||
}
|
||||
|
||||
fn into_token_stream(self) -> TokenStream {
|
||||
self.tts
|
||||
}
|
||||
}
|
||||
110
third-party/vendor/pmutil/src/synom_ext.rs
vendored
Normal file
110
third-party/vendor/pmutil/src/synom_ext.rs
vendored
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
//! Utils for tokens from synom::tokens.
|
||||
|
||||
use proc_macro2::Span;
|
||||
use syn::token::*;
|
||||
|
||||
/// See [SpanExt#as_token][] for usage. Create tokens from [Span][].
|
||||
///
|
||||
///
|
||||
///[SpanExt#as_token]:../trait.SpanExt.html#method.as_token
|
||||
///[Span]:../../proc_macro2/struct.Span.html
|
||||
pub trait FromSpan {
|
||||
fn from_span(span: Span) -> Self;
|
||||
}
|
||||
|
||||
impl FromSpan for Span {
|
||||
#[inline(always)]
|
||||
fn from_span(span: Span) -> Self {
|
||||
span
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_array {
|
||||
($n:expr) => {
|
||||
impl<T: FromSpan + Copy> FromSpan for [T; $n] {
|
||||
#[inline(always)]
|
||||
fn from_span(span: Span) -> Self{
|
||||
let e = FromSpan::from_span(span);
|
||||
[e; $n]
|
||||
}
|
||||
}
|
||||
};
|
||||
($n:expr, $($rest:tt)*) => {
|
||||
impl_array!($n);
|
||||
impl_array!($($rest)*);
|
||||
};
|
||||
}
|
||||
|
||||
impl_array!(1, 2, 3, 4);
|
||||
|
||||
macro_rules! bridge_spans {
|
||||
// Done
|
||||
($t:path) => {
|
||||
impl FromSpan for $t {
|
||||
fn from_span(span: Span) -> Self {
|
||||
let spans = FromSpan::from_span(span);
|
||||
$t { spans }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($t:path, $($rest:tt)+) => {
|
||||
bridge_spans!($t);
|
||||
bridge_spans!($($rest)*);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! bridge {
|
||||
// Done
|
||||
($t:path) => {
|
||||
impl FromSpan for $t {
|
||||
fn from_span(span: Span) -> Self {
|
||||
let span = FromSpan::from_span(span);
|
||||
$t { span }
|
||||
}
|
||||
}
|
||||
};
|
||||
($t:path,) => {
|
||||
bridge!($t);
|
||||
};
|
||||
|
||||
($t:path, $($rest:tt)+) => {
|
||||
bridge!($t);
|
||||
bridge!($($rest)*);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! bridge_group {
|
||||
// Done
|
||||
($t:path) => {
|
||||
impl FromSpan for $t {
|
||||
fn from_span(span: Span) -> Self {
|
||||
$t(span)
|
||||
}
|
||||
}
|
||||
};
|
||||
($t:path,) => {
|
||||
bridge_group!($t);
|
||||
};
|
||||
|
||||
($t:path, $($rest:tt)+) => {
|
||||
bridge_group!($t);
|
||||
bridge_group!($($rest)*);
|
||||
};
|
||||
}
|
||||
|
||||
bridge_spans!(
|
||||
And, AndAnd, AndEq, At, Caret, CaretEq, Colon, Comma, Dollar, Dot, DotDot, DotDotDot, DotDotEq,
|
||||
Eq, EqEq, FatArrow, Ge, Gt, LArrow, Le, Lt, Minus, MinusEq, Ne, Not, Or, OrEq, OrOr, PathSep,
|
||||
Percent, PercentEq, Plus, PlusEq, Pound, Question, RArrow, Semi, Shl, ShlEq, Shr, ShrEq, Slash,
|
||||
SlashEq, Star, StarEq, Tilde, Underscore
|
||||
);
|
||||
|
||||
bridge_group!(Brace, Bracket, Paren);
|
||||
|
||||
bridge!(
|
||||
Abstract, As, Async, Auto, Await, Become, Box, Break, Const, Continue, Crate, Default, Do, Dyn,
|
||||
Else, Enum, Extern, Final, Fn, For, If, Impl, In, Let, Loop, Macro, Match, Mod, Move, Mut,
|
||||
Override, Priv, Pub, Ref, Return, SelfType, SelfValue, Static, Struct, Super, Trait, Try, Type,
|
||||
Typeof, Union, Unsafe, Unsized, Use, Virtual, Where, While, Yield,
|
||||
);
|
||||
Loading…
Add table
Add a link
Reference in a new issue