summaryrefslogtreecommitdiffstats
path: root/third_party/rust/proc-macro-hack/src/quote.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/proc-macro-hack/src/quote.rs')
-rw-r--r--third_party/rust/proc-macro-hack/src/quote.rs114
1 files changed, 114 insertions, 0 deletions
diff --git a/third_party/rust/proc-macro-hack/src/quote.rs b/third_party/rust/proc-macro-hack/src/quote.rs
new file mode 100644
index 0000000000..a3d648d1a4
--- /dev/null
+++ b/third_party/rust/proc-macro-hack/src/quote.rs
@@ -0,0 +1,114 @@
+use proc_macro::{Ident, TokenStream, TokenTree};
+use std::iter;
+
+macro_rules! quote {
+ () => {
+ ::proc_macro::TokenStream::new()
+ };
+ ($($tt:tt)*) => {{
+ let mut tokens = ::proc_macro::TokenStream::new();
+ quote_each_token!(tokens $($tt)*);
+ tokens
+ }};
+}
+
+macro_rules! quote_each_token {
+ ($tokens:ident # $var:ident $($rest:tt)*) => {
+ $crate::quote::Tokens::extend(&mut $tokens, &$var);
+ quote_each_token!($tokens $($rest)*);
+ };
+ ($tokens:ident $ident:ident $($rest:tt)*) => {
+ <::proc_macro::TokenStream as ::std::iter::Extend<_>>::extend(
+ &mut $tokens,
+ ::std::iter::once(
+ ::proc_macro::TokenTree::Ident(
+ ::proc_macro::Ident::new(
+ stringify!($ident),
+ ::proc_macro::Span::call_site(),
+ ),
+ ),
+ ),
+ );
+ quote_each_token!($tokens $($rest)*);
+ };
+ ($tokens:ident ( $($inner:tt)* ) $($rest:tt)*) => {
+ <::proc_macro::TokenStream as ::std::iter::Extend<_>>::extend(
+ &mut $tokens,
+ ::std::iter::once(
+ ::proc_macro::TokenTree::Group(
+ ::proc_macro::Group::new(
+ ::proc_macro::Delimiter::Parenthesis,
+ quote!($($inner)*),
+ ),
+ ),
+ ),
+ );
+ quote_each_token!($tokens $($rest)*);
+ };
+ ($tokens:ident [ $($inner:tt)* ] $($rest:tt)*) => {
+ <::proc_macro::TokenStream as ::std::iter::Extend<_>>::extend(
+ &mut $tokens,
+ ::std::iter::once(
+ ::proc_macro::TokenTree::Group(
+ ::proc_macro::Group::new(
+ ::proc_macro::Delimiter::Bracket,
+ quote!($($inner)*),
+ ),
+ ),
+ ),
+ );
+ quote_each_token!($tokens $($rest)*);
+ };
+ ($tokens:ident { $($inner:tt)* } $($rest:tt)*) => {
+ <::proc_macro::TokenStream as ::std::iter::Extend<_>>::extend(
+ &mut $tokens,
+ ::std::iter::once(
+ ::proc_macro::TokenTree::Group(
+ ::proc_macro::Group::new(
+ ::proc_macro::Delimiter::Brace,
+ quote!($($inner)*),
+ ),
+ ),
+ ),
+ );
+ quote_each_token!($tokens $($rest)*);
+ };
+ ($tokens:ident $punct:tt $($rest:tt)*) => {
+ <::proc_macro::TokenStream as ::std::iter::Extend<_>>::extend(
+ &mut $tokens,
+ stringify!($punct).parse::<::proc_macro::TokenStream>(),
+ );
+ quote_each_token!($tokens $($rest)*);
+ };
+ ($tokens:ident) => {};
+}
+
+pub trait Tokens {
+ fn extend(tokens: &mut TokenStream, var: &Self);
+}
+
+impl Tokens for Ident {
+ fn extend(tokens: &mut TokenStream, var: &Self) {
+ tokens.extend(iter::once(TokenTree::Ident(var.clone())));
+ }
+}
+
+impl Tokens for TokenStream {
+ fn extend(tokens: &mut TokenStream, var: &Self) {
+ tokens.extend(var.clone());
+ }
+}
+
+impl<T: Tokens> Tokens for Option<T> {
+ fn extend(tokens: &mut TokenStream, var: &Self) {
+ if let Some(var) = var {
+ T::extend(tokens, var);
+ }
+ }
+}
+
+impl<T: Tokens> Tokens for &T {
+ fn extend(tokens: &mut TokenStream, var: &Self) {
+ T::extend(tokens, var);
+ }
+}