Skip to content

Commit

Permalink
Implement procedural macro diagnostics
Browse files Browse the repository at this point in the history
commit-id:f06e9653
  • Loading branch information
maciektr committed Mar 11, 2024
1 parent 7cb6bed commit 1ae2137
Show file tree
Hide file tree
Showing 9 changed files with 507 additions and 68 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion plugins/cairo-lang-macro-attributes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,5 @@ repository.workspace = true
proc-macro = true

[dependencies]
camino.workspace = true
quote.workspace = true
syn = { workspace = true, features = ["full", "extra-traits"] }
10 changes: 7 additions & 3 deletions plugins/cairo-lang-macro-attributes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ pub fn attribute_macro(_args: TokenStream, input: TokenStream) -> TokenStream {
#item

#[no_mangle]
pub unsafe extern "C" fn expand(token_stream: cairo_lang_macro_stable::StableTokenStream) -> cairo_lang_macro_stable::StableProcMacroResult {
let token_stream = cairo_lang_macro::TokenStream::from_stable(token_stream);
pub unsafe extern "C" fn expand(stable_token_stream: cairo_lang_macro_stable::StableTokenStream) -> cairo_lang_macro_stable::StableResultWrapper {
let token_stream = cairo_lang_macro::TokenStream::from_stable(&stable_token_stream);
let result = #item_name(token_stream);
result.into_stable()
let result: cairo_lang_macro_stable::StableProcMacroResult = result.into_stable();
cairo_lang_macro_stable::StableResultWrapper {
input: stable_token_stream,
output: result,
}
}
};
TokenStream::from(expanded)
Expand Down
37 changes: 37 additions & 0 deletions plugins/cairo-lang-macro-stable/src/ffi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/// This struct encapsulates a stable ABI representation of information required to construct a slice.
///
/// Please be aware that the memory management of values passing the FFI-barrier is tricky.
/// The memory must be freed on the same side of the barrier, where the allocation was made.
#[repr(C)]
#[derive(Debug)]
#[doc(hidden)]
pub struct StableSlice<T> {
ptr: *mut T,
len: usize,
}

impl<T> StableSlice<T> {
/// Create a new `StableSlice` from a Vector.
/// Note that the vector will not be deallocated automatically.
/// Please make sure to use `into_owned` afterward, to free the memory.
pub fn new(mut x: Vec<T>) -> Self {
x.shrink_to_fit();
assert_eq!(x.len(), x.capacity());
let ptr = x.as_mut_ptr();
let len = x.len();
std::mem::forget(x);
Self { ptr, len }
}

/// Convert to owned vector.
pub fn into_owned(self) -> Vec<T> {
unsafe { Vec::from_raw_parts(self.ptr, self.len, self.len) }
}

/// Returns raw pointer and length.
/// Can be used to construct a slice.
/// No ownership is transferred.
pub fn raw_parts(&self) -> (*mut T, usize) {
(self.ptr, self.len)
}
}
46 changes: 41 additions & 5 deletions plugins/cairo-lang-macro-stable/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,71 @@
use crate::ffi::StableSlice;
use std::ffi::{CStr, CString};
use std::num::NonZeroU8;
use std::os::raw::c_char;

pub mod ffi;

/// Token stream.
///
/// This struct implements FFI-safe stable ABI.
#[repr(C)]
#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct StableTokenStream(*mut c_char);

#[repr(C)]
#[derive(Debug, Clone)]
#[derive(Debug)]
pub enum StableAuxData {
None,
Some(*mut c_char),
}

/// Diagnostic returned by the procedural macro.
///
/// This struct implements FFI-safe stable ABI.
#[repr(C)]
#[derive(Debug)]
pub struct StableDiagnostic {
pub message: *mut c_char,
pub severity: StableSeverity,
}

/// The severity of a diagnostic.
///
/// This struct implements FFI-safe stable ABI.
pub type StableSeverity = NonZeroU8;

/// Procedural macro result.
///
/// This struct implements FFI-safe stable ABI.
#[repr(C)]
#[derive(Debug, Clone)]
#[derive(Debug)]
pub enum StableProcMacroResult {
/// Plugin has not taken any action.
Leave,
Leave {
diagnostics: StableSlice<StableDiagnostic>,
// diagnostics: *mut StableDiagnostic,
// diagnostics_n: usize,
},
/// Plugin generated [`StableTokenStream`] replacement.
Replace {
diagnostics: StableSlice<StableDiagnostic>,
token_stream: StableTokenStream,
aux_data: StableAuxData,
// diagnostics: *mut StableDiagnostic,
// diagnostics_n: usize,
},
/// Plugin ordered item removal.
Remove,
Remove {
diagnostics: StableSlice<StableDiagnostic>,
// diagnostics: *mut StableDiagnostic,
// diagnostics_n: usize,
},
}

#[repr(C)]
pub struct StableResultWrapper {
pub input: StableTokenStream,
pub output: StableProcMacroResult,
}

impl StableTokenStream {
Expand Down
Loading

0 comments on commit 1ae2137

Please sign in to comment.