use std::collections::HashMap;
use crate::abi::type_registry::{ResolvedTypeRef, TypeRegistry};
use crate::abi::{ClassIR, EnumIR, InterfaceIR, SpanIR, TypeAliasIR};
use crate::import_registry::ImportRegistry;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MacroKind {
Derive,
Attribute,
Call,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TargetIR {
Class(ClassIR),
Enum(EnumIR),
Interface(InterfaceIR),
TypeAlias(TypeAliasIR),
Function,
Other,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MacroContextIR {
pub abi_version: u32,
pub macro_kind: MacroKind,
pub macro_name: String,
pub module_path: String,
pub decorator_span: SpanIR,
#[serde(default)]
pub macro_name_span: Option<SpanIR>,
pub target_span: SpanIR,
pub file_name: String,
pub target: TargetIR,
pub target_source: String,
#[serde(default)]
pub import_registry: ImportRegistry,
#[serde(default)]
pub config: Option<crate::config::MacroforgeConfig>,
#[serde(default)]
pub type_registry: Option<TypeRegistry>,
#[serde(default)]
pub resolved_fields: Option<HashMap<String, ResolvedTypeRef>>,
}
impl MacroContextIR {
pub fn new_derive_class(
macro_name: String,
module_path: String,
decorator_span: SpanIR,
target_span: SpanIR,
file_name: String,
class: ClassIR,
target_source: String,
) -> Self {
Self {
abi_version: 1,
macro_kind: MacroKind::Derive,
macro_name,
module_path,
decorator_span,
macro_name_span: None,
target_span,
file_name,
target: TargetIR::Class(class),
target_source,
import_registry: ImportRegistry::new(),
config: None,
type_registry: None,
resolved_fields: None,
}
}
pub fn with_macro_name_span(mut self, span: SpanIR) -> Self {
self.macro_name_span = Some(span);
self
}
pub fn error_span(&self) -> SpanIR {
self.macro_name_span.unwrap_or(self.decorator_span)
}
pub fn as_class(&self) -> Option<&ClassIR> {
match &self.target {
TargetIR::Class(class) => Some(class),
_ => None,
}
}
pub fn as_enum(&self) -> Option<&EnumIR> {
match &self.target {
TargetIR::Enum(enum_ir) => Some(enum_ir),
_ => None,
}
}
pub fn as_interface(&self) -> Option<&InterfaceIR> {
match &self.target {
TargetIR::Interface(interface_ir) => Some(interface_ir),
_ => None,
}
}
pub fn as_type_alias(&self) -> Option<&TypeAliasIR> {
match &self.target {
TargetIR::TypeAlias(type_alias_ir) => Some(type_alias_ir),
_ => None,
}
}
pub fn new_derive_interface(
macro_name: String,
module_path: String,
decorator_span: SpanIR,
target_span: SpanIR,
file_name: String,
interface: InterfaceIR,
target_source: String,
) -> Self {
Self {
abi_version: 1,
macro_kind: MacroKind::Derive,
macro_name,
module_path,
decorator_span,
macro_name_span: None,
target_span,
file_name,
target: TargetIR::Interface(interface),
target_source,
import_registry: ImportRegistry::new(),
config: None,
type_registry: None,
resolved_fields: None,
}
}
pub fn new_derive_type_alias(
macro_name: String,
module_path: String,
decorator_span: SpanIR,
target_span: SpanIR,
file_name: String,
type_alias: TypeAliasIR,
target_source: String,
) -> Self {
Self {
abi_version: 1,
macro_kind: MacroKind::Derive,
macro_name,
module_path,
decorator_span,
macro_name_span: None,
target_span,
file_name,
target: TargetIR::TypeAlias(type_alias),
target_source,
import_registry: ImportRegistry::new(),
config: None,
type_registry: None,
resolved_fields: None,
}
}
pub fn new_derive_enum(
macro_name: String,
module_path: String,
decorator_span: SpanIR,
target_span: SpanIR,
file_name: String,
enum_ir: EnumIR,
target_source: String,
) -> Self {
Self {
abi_version: 1,
macro_kind: MacroKind::Derive,
macro_name,
module_path,
decorator_span,
macro_name_span: None,
target_span,
file_name,
target: TargetIR::Enum(enum_ir),
target_source,
import_registry: ImportRegistry::new(),
config: None,
type_registry: None,
resolved_fields: None,
}
}
}