Skip to content

Commit

Permalink
Support renaming in custom_keyword macro
Browse files Browse the repository at this point in the history
  • Loading branch information
ModProg committed Sep 7, 2024
1 parent 6232266 commit b642bcd
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 15 deletions.
40 changes: 25 additions & 15 deletions src/custom_keyword.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
/// }
/// ```
///
/// To specify a different name for the resulting Rust item, a name can be
/// provided:
///
/// ```
/// syn::custom_keyword!(whatever as Whatever);
/// ```
///
/// The generated syntax tree node supports the following operations just like
/// any built-in keyword token.
///
Expand Down Expand Up @@ -89,6 +96,9 @@
#[macro_export]
macro_rules! custom_keyword {
($ident:ident) => {
$crate::custom_keyword!{$ident as $ident}
};
($keyword:ident as $ident:ident) => {
#[allow(non_camel_case_types)]
pub struct $ident {
#[allow(dead_code)]
Expand All @@ -114,10 +124,10 @@ macro_rules! custom_keyword {
}
}

$crate::impl_parse_for_custom_keyword!($ident);
$crate::impl_to_tokens_for_custom_keyword!($ident);
$crate::impl_parse_for_custom_keyword!($keyword as $ident);
$crate::impl_to_tokens_for_custom_keyword!($keyword as $ident);
$crate::impl_clone_for_custom_keyword!($ident);
$crate::impl_extra_traits_for_custom_keyword!($ident);
$crate::impl_extra_traits_for_custom_keyword!($keyword as $ident);
};
};
}
Expand All @@ -127,33 +137,33 @@ macro_rules! custom_keyword {
#[doc(hidden)]
#[macro_export]
macro_rules! impl_parse_for_custom_keyword {
($ident:ident) => {
($keyword:ident as $ident:ident) => {
// For peek.
impl $crate::__private::CustomToken for $ident {
fn peek(cursor: $crate::buffer::Cursor) -> $crate::__private::bool {
if let $crate::__private::Some((ident, _rest)) = cursor.ident() {
ident == $crate::__private::stringify!($ident)
ident == $crate::__private::stringify!($keyword)
} else {
false
}
}

fn display() -> &'static $crate::__private::str {
$crate::__private::concat!("`", $crate::__private::stringify!($ident), "`")
$crate::__private::concat!("`", $crate::__private::stringify!($keyword), "`")
}
}

impl $crate::parse::Parse for $ident {
fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> {
input.step(|cursor| {
if let $crate::__private::Some((ident, rest)) = cursor.ident() {
if ident == $crate::__private::stringify!($ident) {
if ident == $crate::__private::stringify!($keyword) {
return $crate::__private::Ok(($ident { span: ident.span() }, rest));
}
}
$crate::__private::Err(cursor.error($crate::__private::concat!(
"expected `",
$crate::__private::stringify!($ident),
$crate::__private::stringify!($keyword),
"`",
)))
})
Expand All @@ -167,18 +177,18 @@ macro_rules! impl_parse_for_custom_keyword {
#[doc(hidden)]
#[macro_export]
macro_rules! impl_parse_for_custom_keyword {
($ident:ident) => {};
($keyword:ident as $ident:ident) => {};
}

// Not public API.
#[cfg(feature = "printing")]
#[doc(hidden)]
#[macro_export]
macro_rules! impl_to_tokens_for_custom_keyword {
($ident:ident) => {
($keyword:ident as $ident:ident) => {
impl $crate::__private::ToTokens for $ident {
fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) {
let ident = $crate::Ident::new($crate::__private::stringify!($ident), self.span);
let ident = $crate::Ident::new($crate::__private::stringify!($keyword), self.span);
$crate::__private::TokenStreamExt::append(tokens, ident);
}
}
Expand All @@ -190,7 +200,7 @@ macro_rules! impl_to_tokens_for_custom_keyword {
#[doc(hidden)]
#[macro_export]
macro_rules! impl_to_tokens_for_custom_keyword {
($ident:ident) => {};
($keyword:ident as $ident:ident) => {};
}

// Not public API.
Expand Down Expand Up @@ -223,14 +233,14 @@ macro_rules! impl_clone_for_custom_keyword {
#[doc(hidden)]
#[macro_export]
macro_rules! impl_extra_traits_for_custom_keyword {
($ident:ident) => {
($keyword:ident as $ident:ident) => {
impl $crate::__private::Debug for $ident {
fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::FmtResult {
$crate::__private::Formatter::write_str(
f,
$crate::__private::concat!(
"Keyword [",
$crate::__private::stringify!($ident),
$crate::__private::stringify!($keyword),
"]",
),
)
Expand All @@ -256,5 +266,5 @@ macro_rules! impl_extra_traits_for_custom_keyword {
#[doc(hidden)]
#[macro_export]
macro_rules! impl_extra_traits_for_custom_keyword {
($ident:ident) => {};
($keyword:ident as $ident:ident) => {};
}
30 changes: 30 additions & 0 deletions tests/custom_keyword.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use proc_macro2::Span;
use quote::quote;
use syn::{
custom_keyword,
parse::{Parse, ParseStream, Parser},
};

custom_keyword!(implicit);
custom_keyword!(explicit as Explicit);

#[test]
fn parsing() {
(|input: ParseStream| {
assert!(input.peek(implicit));
implicit::parse(input).unwrap();
assert!(input.peek(Explicit));
Explicit::parse(input).unwrap();
Ok(())
})
.parse2(quote!(implicit explicit));
}

#[test]
fn printing() {
let implicit = implicit(Span::call_site());
let explicit = Explicit(Span::call_site());

assert_eq!(format!("{implicit:?} {explicit:?}"), "Keyword [implicit] Keyword [explicit]");
assert_eq!(quote!(#implicit #explicit).to_string(), "implicit explicit");
}

0 comments on commit b642bcd

Please sign in to comment.