@macroforge/mcp-server
Version:
MCP server for Macroforge documentation and code analysis
93 lines (80 loc) • 4.04 kB
Markdown
## DeriveInput Structure
Rust
```
struct DeriveInput {
pub ident: Ident, // The type name and its span
pub span: SpanIR, // Span of the type definition
pub attrs: Vec<Attribute>, // Decorators (excluding @derive)
pub data: Data, // The parsed type data
pub context: MacroContextIR, // The macro context
// Helper methods
fn name(&self) -> &str; // The type name
fn as_class(&self) -> Option<&DataClass>;
fn as_interface(&self) -> Option<&DataInterface>;
fn as_enum(&self) -> Option<&DataEnum>;
fn as_type_alias(&self) -> Option<&DataTypeAlias>;
fn decorator_span(&self) -> SpanIR; // The whole @derive(...)
fn macro_name_span(&self) -> Option<SpanIR>; // This macro's name inside it
fn error_span(&self) -> SpanIR; // Where to point an error
fn target_span(&self) -> SpanIR; // The declaration
fn body_span(&self) -> Option<SpanIR>; // The body; None for enums and type aliases
fn from_context(ctx: MacroContextIR) -> Result<Self, TsSynError>;
}
struct Attribute {
fn name(&self) -> &str; // e.g. "endec"
fn args(&self) -> &str; // the arguments as written
fn span(&self) -> SpanIR;
}
enum Data {
Class(DataClass),
Interface(DataInterface),
Enum(DataEnum),
TypeAlias(DataTypeAlias),
}
impl DataClass {
fn fields(&self) -> &[FieldIR];
fn methods(&self) -> &[MethodSigIR];
fn field_names(&self) -> impl Iterator<Item = &str>;
fn field(&self, name: &str) -> Option<&FieldIR>;
fn method(&self, name: &str) -> Option<&MethodSigIR>;
fn body_span(&self) -> SpanIR; // For inserting code into class body
fn type_params(&self) -> &[TypeParamIR]; // Generic type parameters
fn heritage(&self) -> &[String]; // extends/implements clauses
fn is_abstract(&self) -> bool;
}
impl DataInterface {
fn fields(&self) -> &[InterfaceFieldIR];
fn methods(&self) -> &[InterfaceMethodIR];
fn field_names(&self) -> impl Iterator<Item = &str>;
fn field(&self, name: &str) -> Option<&InterfaceFieldIR>;
fn method(&self, name: &str) -> Option<&InterfaceMethodIR>;
fn body_span(&self) -> SpanIR;
fn type_params(&self) -> &[TypeParamIR];
fn heritage(&self) -> &[String]; // extends clauses
}
impl DataEnum {
fn variants(&self) -> &[EnumVariantIR];
fn variant_names(&self) -> impl Iterator<Item = &str>;
fn variant(&self, name: &str) -> Option<&EnumVariantIR>;
}
impl DataTypeAlias {
fn body(&self) -> &TypeBody;
fn type_params(&self) -> &[TypeParamIR];
fn is_union(&self) -> bool;
fn is_intersection(&self) -> bool;
fn is_object(&self) -> bool;
fn is_tuple(&self) -> bool;
fn is_alias(&self) -> bool;
fn as_union(&self) -> Option<&[TypeMember]>;
fn as_intersection(&self) -> Option<&[TypeMember]>;
fn as_object(&self) -> Option<&[InterfaceFieldIR]>;
fn as_tuple(&self) -> Option<&[String]>;
fn as_alias(&self) -> Option<&str>;
}
```
Each `Data*` wrapper keeps the full IR in its `inner` field; see
[Context and IR](../../docs/custom-macros/context-and-ir) for every type.
Note
Inside a template, write the type's name with `@{input.name()}`. `input.ident` is a `ts_syn::Ident`,
which records where the name is, and templates do not interpolate it; `ts_ident!(...)` makes the
identifier type that they do.