MacroDispatcher

Struct MacroDispatcher 

Source
pub struct MacroDispatcher { /* private fields */ }
Expand description

Routes macro calls to registered implementations.

The dispatcher is the bridge between the expansion engine and individual macro implementations. It handles lookup, validation, and execution.

§Safety

The dispatcher catches all panics from macro execution, converting them to error diagnostics. This ensures a single misbehaving macro doesn’t crash the entire expansion process.

§Example

use macroforge_ts::host::{MacroRegistry, MacroDispatcher, DiagnosticLevel, MacroKind};
use macroforge_ts::ts_syn::abi::{MacroContextIR, SpanIR, TargetIR, ClassIR};

let registry = MacroRegistry::new();
// ... register macros in the registry ...

let dispatcher = MacroDispatcher::new(registry);

// Create a macro context (normally built by the expander)
let class_ir = ClassIR {
    name: "User".to_string(),
    span: SpanIR::new(10, 50),
    body_span: SpanIR::new(20, 49),
    is_abstract: false,
    type_params: vec![],
    heritage: vec![],
    decorators: vec![],
    decorators_ast: vec![],
    fields: vec![],
    methods: vec![],
    members: vec![],
};

let macro_context = MacroContextIR {
    abi_version: 1,
    macro_kind: MacroKind::Derive,
    macro_name: "Debug".to_string(),
    module_path: "builtin".to_string(),
    decorator_span: SpanIR::new(0, 10),
    macro_name_span: None,
    target_span: SpanIR::new(10, 50),
    file_name: "test.ts".to_string(),
    target: TargetIR::Class(class_ir),
    target_source: "class User {}".to_string(),
};

// Dispatch the macro call
let result = dispatcher.dispatch(macro_context);

// Handle diagnostics
for diag in &result.diagnostics {
    if diag.level == DiagnosticLevel::Error {
        eprintln!("Error: {}", diag.message);
    }
}

Implementations§

Source§

impl MacroDispatcher

Source

pub fn new(registry: MacroRegistry) -> Self

Creates a new dispatcher with the given registry.

§Arguments
  • registry - The macro registry to use for lookups
Source

pub fn dispatch(&self, ctx: MacroContextIR) -> MacroResult

Dispatches a macro call to its registered implementation.

This is the main entry point for macro execution. It performs:

  1. Registry lookup with fallback resolution
  2. ABI version compatibility checking
  3. TsStream creation from context
  4. Macro execution with panic catching
§Arguments
  • ctx - The macro invocation context containing all information needed for execution (macro name, target code, file info, etc.)
§Returns

A MacroResult containing:

  • runtime_patches - Code patches to apply to the source
  • type_patches - Patches for type declarations
  • diagnostics - Errors, warnings, and info messages
§Error Handling

All errors are returned as diagnostics, never as panics or Results:

  • Unknown macro → Error diagnostic
  • ABI mismatch → Error diagnostic with versions
  • Execution panic → Error diagnostic with panic message
Source

pub fn registry(&self) -> &MacroRegistry

Returns a reference to the underlying registry.

Useful for debugging and introspection.

Auto Trait Implementations§

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> Send for T
where T: ?Sized,

Source§

impl<T> Sync for T
where T: ?Sized,