Skip to content

Commit

Permalink
Replace result enum with single struct
Browse files Browse the repository at this point in the history
commit-id:3f7d4d4c
  • Loading branch information
maciektr committed Apr 12, 2024
1 parent 35abd5d commit 112aa2f
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 382 deletions.
54 changes: 14 additions & 40 deletions plugins/cairo-lang-macro-attributes/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use proc_macro::TokenStream;
use quote::quote;
use quote::{quote, ToTokens};
use scarb_stable_hash::short_hash;
use syn::spanned::Spanned;
use syn::{parse_macro_input, ItemFn};
Expand All @@ -11,35 +11,20 @@ use syn::{parse_macro_input, ItemFn};
/// Note, that this macro can be used multiple times, to define multiple independent attribute macros.
#[proc_macro_attribute]
pub fn attribute_macro(_args: TokenStream, input: TokenStream) -> TokenStream {
let item: ItemFn = parse_macro_input!(input as ItemFn);
let original_item_name = item.sig.ident.to_string();
let item = hide_name(item);
let item_name = &item.sig.ident;

let callback_link = format!(
"EXPANSIONS_DESERIALIZE_{}",
item_name.to_string().to_uppercase()
);
let callback_link = syn::Ident::new(callback_link.as_str(), item.span());

let expanded = quote! {
#item

#[::cairo_lang_macro::linkme::distributed_slice(::cairo_lang_macro::MACRO_DEFINITIONS_SLICE)]
#[linkme(crate = ::cairo_lang_macro::linkme)]
static #callback_link: ::cairo_lang_macro::ExpansionDefinition =
::cairo_lang_macro::ExpansionDefinition{
name: #original_item_name,
kind: ::cairo_lang_macro::ExpansionKind::Attr,
fun: #item_name,
};
};

TokenStream::from(expanded)
macro_helper(input, quote!(::cairo_lang_macro::ExpansionKind::Attr))
}

/// Constructs the inline macro implementation.
///
/// This macro hides the conversion to stable ABI structs from the user.
///
/// Note, that this macro can be used multiple times, to define multiple independent attribute macros.
#[proc_macro_attribute]
pub fn inline_macro(_args: TokenStream, input: TokenStream) -> TokenStream {
macro_helper(input, quote!(::cairo_lang_macro::ExpansionKind::Inline))
}

fn macro_helper(input: TokenStream, kind: impl ToTokens) -> TokenStream {
let item: ItemFn = parse_macro_input!(input as ItemFn);
let original_item_name = item.sig.ident.to_string();
let item = hide_name(item);
Expand All @@ -49,32 +34,21 @@ pub fn inline_macro(_args: TokenStream, input: TokenStream) -> TokenStream {
"EXPANSIONS_DESERIALIZE_{}",
item_name.to_string().to_uppercase()
);
let callback_link = syn::Ident::new(callback_link.as_str(), item.span());

// We wrap original function with `InlineProcMacroResult` to `ProcMacroResult` conversion.
// This stems from the fact, that `ProcMacroResult::Remove` does not really make sense for inline macros.
let wrapper_name = format!("{item_name}_inline_wrapper");
let wrapper_name = syn::Ident::new(wrapper_name.as_str(), item.span());
let callback_link = syn::Ident::new(callback_link.as_str(), item.span());

let expanded = quote! {
#item

fn #wrapper_name(token_stream: ::cairo_lang_macro::TokenStream) -> ::cairo_lang_macro::ProcMacroResult {
// Assign function pointer, to validate type.
let f: fn(::cairo_lang_macro::TokenStream) -> ::cairo_lang_macro::InlineProcMacroResult = #item_name;
f(token_stream).into()
}

#[::cairo_lang_macro::linkme::distributed_slice(::cairo_lang_macro::MACRO_DEFINITIONS_SLICE)]
#[linkme(crate = ::cairo_lang_macro::linkme)]
static #callback_link: ::cairo_lang_macro::ExpansionDefinition =
::cairo_lang_macro::ExpansionDefinition{
name: #original_item_name,
kind: ::cairo_lang_macro::ExpansionKind::Inline,
fun: #wrapper_name,
kind: #kind,
fun: #item_name,
};
};

TokenStream::from(expanded)
}

Expand Down
21 changes: 5 additions & 16 deletions plugins/cairo-lang-macro-stable/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,11 @@ pub type StableSeverity = NonZeroU8;
/// This struct implements FFI-safe stable ABI.
#[repr(C)]
#[derive(Debug)]
pub enum StableProcMacroResult {
/// Plugin has not taken any action.
Leave {
diagnostics: StableSlice<StableDiagnostic>,
},
/// Plugin generated [`StableTokenStream`] replacement.
Replace {
diagnostics: StableSlice<StableDiagnostic>,
token_stream: StableTokenStream,
aux_data: StableAuxData,
full_path_markers: StableSlice<*mut c_char>,
},
/// Plugin ordered item removal.
Remove {
diagnostics: StableSlice<StableDiagnostic>,
},
pub struct StableProcMacroResult {
pub token_stream: StableTokenStream,
pub diagnostics: StableSlice<StableDiagnostic>,
pub aux_data: StableAuxData,
pub full_path_markers: StableSlice<*mut c_char>,
}

#[repr(C)]
Expand Down
166 changes: 46 additions & 120 deletions plugins/cairo-lang-macro/src/types/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,46 +19,21 @@ impl ProcMacroResult {
/// # Safety
#[doc(hidden)]
pub fn into_stable(self) -> StableProcMacroResult {
match self {
ProcMacroResult::Leave { diagnostics } => {
let diagnostics = diagnostics
.into_iter()
.map(|d| d.into_stable())
.collect::<Vec<_>>();
StableProcMacroResult::Leave {
diagnostics: StableSlice::new(diagnostics),
}
}
ProcMacroResult::Remove { diagnostics } => {
let diagnostics = diagnostics
.into_iter()
.map(|d| d.into_stable())
.collect::<Vec<_>>();
StableProcMacroResult::Remove {
diagnostics: StableSlice::new(diagnostics),
}
}
ProcMacroResult::Replace {
token_stream,
aux_data,
diagnostics,
full_path_markers,
} => {
let diagnostics = diagnostics
.into_iter()
.map(|d| d.into_stable())
.collect::<Vec<_>>();
let full_path_markers = full_path_markers
.into_iter()
.map(|m| CString::new(m).unwrap().into_raw())
.collect::<Vec<_>>();
StableProcMacroResult::Replace {
token_stream: token_stream.into_stable(),
aux_data: AuxData::maybe_into_stable(aux_data),
diagnostics: StableSlice::new(diagnostics),
full_path_markers: StableSlice::new(full_path_markers),
}
}
let diagnostics = self
.diagnostics
.into_iter()
.map(|d| d.into_stable())
.collect::<Vec<_>>();
let full_path_markers = self
.full_path_markers
.into_iter()
.map(|m| CString::new(m).unwrap().into_raw())
.collect::<Vec<_>>();
StableProcMacroResult {
token_stream: self.token_stream.into_stable(),
aux_data: AuxData::maybe_into_stable(self.aux_data),
diagnostics: StableSlice::new(diagnostics),
full_path_markers: StableSlice::new(full_path_markers),
}
}

Expand All @@ -69,46 +44,21 @@ impl ProcMacroResult {
/// # Safety
#[doc(hidden)]
pub unsafe fn from_stable(result: &StableProcMacroResult) -> Self {
match result {
StableProcMacroResult::Leave { diagnostics } => {
let (ptr, n) = diagnostics.raw_parts();
let diagnostics = slice::from_raw_parts(ptr, n)
.iter()
.map(|d| Diagnostic::from_stable(d))
.collect::<Vec<_>>();
ProcMacroResult::Leave { diagnostics }
}
StableProcMacroResult::Remove { diagnostics } => {
let (ptr, n) = diagnostics.raw_parts();
let diagnostics = slice::from_raw_parts(ptr, n)
.iter()
.map(|d| Diagnostic::from_stable(d))
.collect::<Vec<_>>();
ProcMacroResult::Remove { diagnostics }
}
StableProcMacroResult::Replace {
token_stream,
aux_data,
diagnostics,
full_path_markers,
} => {
let (ptr, n) = diagnostics.raw_parts();
let diagnostics = slice::from_raw_parts(ptr, n)
.iter()
.map(|d| Diagnostic::from_stable(d))
.collect::<Vec<_>>();
let (ptr, n) = full_path_markers.raw_parts();
let full_path_markers = slice::from_raw_parts(ptr, n)
.iter()
.map(|m| from_raw_cstr(*m))
.collect::<Vec<_>>();
ProcMacroResult::Replace {
token_stream: TokenStream::from_stable(token_stream),
aux_data: AuxData::from_stable(aux_data),
diagnostics,
full_path_markers,
}
}
let (ptr, n) = result.diagnostics.raw_parts();
let diagnostics = slice::from_raw_parts(ptr, n)
.iter()
.map(|d| Diagnostic::from_stable(d))
.collect::<Vec<_>>();
let (ptr, n) = result.full_path_markers.raw_parts();
let full_path_markers = slice::from_raw_parts(ptr, n)
.iter()
.map(|m| from_raw_cstr(*m))
.collect::<Vec<_>>();
ProcMacroResult {
token_stream: TokenStream::from_stable(&result.token_stream),
diagnostics,
full_path_markers,
aux_data: AuxData::from_stable(&result.aux_data),
}
}

Expand All @@ -120,46 +70,22 @@ impl ProcMacroResult {
/// # Safety
#[doc(hidden)]
pub unsafe fn from_owned_stable(result: StableProcMacroResult) -> Self {
match result {
StableProcMacroResult::Leave { diagnostics } => {
let diagnostics = diagnostics.into_owned();
let diagnostics = diagnostics
.into_iter()
.map(|d| Diagnostic::from_owned_stable(d))
.collect::<Vec<_>>();
ProcMacroResult::Leave { diagnostics }
}
StableProcMacroResult::Remove { diagnostics } => {
let diagnostics = diagnostics.into_owned();
let diagnostics = diagnostics
.into_iter()
.map(|d| Diagnostic::from_owned_stable(d))
.collect::<Vec<_>>();
ProcMacroResult::Remove { diagnostics }
}
StableProcMacroResult::Replace {
token_stream,
aux_data,
diagnostics,
full_path_markers,
} => {
let diagnostics = diagnostics.into_owned();
let diagnostics = diagnostics
.into_iter()
.map(|d| Diagnostic::from_owned_stable(d))
.collect::<Vec<_>>();
let full_path_markers = full_path_markers
.into_owned()
.iter()
.map(|m| from_raw_cstring(*m))
.collect::<Vec<_>>();
ProcMacroResult::Replace {
token_stream: TokenStream::from_owned_stable(token_stream),
aux_data: AuxData::from_owned_stable(aux_data),
diagnostics,
full_path_markers,
}
}
let diagnostics = result.diagnostics.into_owned();
let diagnostics = diagnostics
.into_iter()
.map(|d| Diagnostic::from_owned_stable(d))
.collect::<Vec<_>>();
let full_path_markers = result
.full_path_markers
.into_owned()
.iter()
.map(|m| from_raw_cstring(*m))
.collect::<Vec<_>>();
ProcMacroResult {
token_stream: TokenStream::from_owned_stable(result.token_stream),
aux_data: AuxData::from_owned_stable(result.aux_data),
diagnostics,
full_path_markers,
}
}
}
Expand Down
Loading

0 comments on commit 112aa2f

Please sign in to comment.