1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//! Helper macros for ergonomic code generation.
//!
//! This module provides convenience macros for common code generation
//! patterns when building macro implementations. These macros work with
//! the AST construction macros from [`lib.rs`](crate) and SWC's AST types.
//!
//! ## Available Macros
//!
//! | Macro | Purpose |
//! |-------|---------|
//! | `proto_method!` | Assign a method to a class prototype |
//!
//! ## Common Patterns
//!
//! ### Adding Methods to Classes
//!
//! Use `proto_method!` to generate `Class.prototype.method = function() {...}`:
//!
//! ```rust
//! use macroforge_ts_syn::{proto_method, ts_ident};
//! use macroforge_ts_syn::swc_ecma_ast::Stmt;
//!
//! // Generate: User.prototype.toJSON = function() { return {...}; }
//! let class_name = ts_ident!("User");
//! let body: Vec<Stmt> = vec![];
//!
//! let _stmt = proto_method!(class_name, "toJSON", body);
//! ```
//!
//! ## Related Macros
//!
//! For constructing AST nodes, see the macros in [`lib.rs`](crate):
//! - [`ident!`](crate::ident!) - Create identifier expressions
//! - [`member_expr!`](crate::member_expr!) - Create member access expressions
//! - [`fn_assign!`](crate::fn_assign!) - Create function assignment statements
//! - [`stmt_vec!`](crate::stmt_vec!) - Create vectors of statements
/// Creates a method assignment on a class prototype.
///
/// This macro generates code of the form:
/// ```typescript
/// ClassName.prototype.methodName = function() { /* body */ }
/// ```
///
/// This is the standard pattern for adding methods to classes in JavaScript/TypeScript
/// when you need to add methods outside the class declaration (e.g., in macro-generated code).
///
/// # Arguments
///
/// - `$class` - An identifier expression for the class name (use [`ident!`](crate::ident!))
/// - `$method` - A string literal for the method name
/// - `$body` - A `Vec<Stmt>` containing the function body
///
/// # Example: Basic Usage
///
/// ```rust
/// use macroforge_ts_syn::{proto_method, ts_ident};
/// use macroforge_ts_syn::swc_ecma_ast::Stmt;
///
/// // Generate: MyClass.prototype.toString = function() { return "MyClass"; }
/// let body_stmts: Vec<Stmt> = vec![];
///
/// let _stmt = proto_method!(ts_ident!("MyClass"), "toString", body_stmts);
/// ```
///
/// # Example: In a Derive Macro
///
/// ```rust,ignore
/// fn derive_debug(input: &DeriveInput) -> MacroResult {
/// let class = input.as_class().expect("Expected class");
/// let class_name = ts_ident!(&input.name());
///
/// // Build the debug() method body
/// let body = vec![
/// ts_quote!( return `${#class_name} { ... }`; as Stmt ),
/// ];
///
/// let method_stmt = proto_method!(class_name, "debug", body);
///
/// // Return patch that inserts this method after the class
/// MacroResult {
/// runtime_patches: vec![
/// Patch::InsertAfter {
/// target: input.target_span(),
/// code: method_stmt.into(),
/// source_macro: Some("Debug".into()),
/// }
/// ],
/// ..Default::default()
/// }
/// }
/// ```
///
/// # Under the Hood
///
/// This macro expands to:
/// ```rust,ignore
/// fn_assign!(
/// member_expr!(Expr::Ident(class), "prototype"),
/// method_name,
/// body
/// )
/// ```