1pub mod abi;
107pub mod derive;
108pub mod errors;
109pub mod lower;
110pub mod parse;
111pub mod quote_helpers;
112pub mod stream;
113
114pub use abi::*;
115pub use derive::*;
116pub use errors::*;
117pub use lower::*;
118pub use stream::*;
119#[cfg(feature = "swc")]
120pub use swc_core::quote;
121
122#[cfg(feature = "swc")]
124pub use swc_core;
125
126#[cfg(feature = "swc")]
128pub use swc_core::common as swc_common;
129#[cfg(feature = "swc")]
130pub use swc_core::ecma::ast as swc_ecma_ast;
131
132#[cfg(feature = "swc")]
144pub trait ToTsExpr {
145 fn to_ts_expr(self) -> swc_core::ecma::ast::Expr;
146}
147
148#[cfg(feature = "swc")]
149impl ToTsExpr for swc_core::ecma::ast::Expr {
150 fn to_ts_expr(self) -> swc_core::ecma::ast::Expr {
151 self
152 }
153}
154
155#[cfg(feature = "swc")]
156impl ToTsExpr for Box<swc_core::ecma::ast::Expr> {
157 fn to_ts_expr(self) -> swc_core::ecma::ast::Expr {
158 *self
159 }
160}
161
162#[cfg(feature = "swc")]
163impl ToTsExpr for &swc_core::ecma::ast::Expr {
164 fn to_ts_expr(self) -> swc_core::ecma::ast::Expr {
165 self.clone()
166 }
167}
168
169#[cfg(feature = "swc")]
170impl ToTsExpr for swc_core::ecma::ast::Ident {
171 fn to_ts_expr(self) -> swc_core::ecma::ast::Expr {
172 swc_core::ecma::ast::Expr::Ident(self)
173 }
174}
175
176#[cfg(feature = "swc")]
177impl ToTsExpr for &swc_core::ecma::ast::Ident {
178 fn to_ts_expr(self) -> swc_core::ecma::ast::Expr {
179 swc_core::ecma::ast::Expr::Ident(self.clone())
180 }
181}
182
183#[cfg(feature = "swc")]
184impl ToTsExpr for String {
185 fn to_ts_expr(self) -> swc_core::ecma::ast::Expr {
186 swc_core::ecma::ast::Expr::Lit(swc_core::ecma::ast::Lit::Str(swc_core::ecma::ast::Str {
187 span: swc_core::common::DUMMY_SP,
188 value: self.into(),
189 raw: None,
190 }))
191 }
192}
193
194#[cfg(feature = "swc")]
195impl ToTsExpr for &String {
196 fn to_ts_expr(self) -> swc_core::ecma::ast::Expr {
197 self.clone().to_ts_expr()
198 }
199}
200
201#[cfg(feature = "swc")]
202impl ToTsExpr for &str {
203 fn to_ts_expr(self) -> swc_core::ecma::ast::Expr {
204 swc_core::ecma::ast::Expr::Lit(swc_core::ecma::ast::Lit::Str(swc_core::ecma::ast::Str {
205 span: swc_core::common::DUMMY_SP,
206 value: self.into(),
207 raw: None,
208 }))
209 }
210}
211
212#[cfg(feature = "swc")]
213impl ToTsExpr for bool {
214 fn to_ts_expr(self) -> swc_core::ecma::ast::Expr {
215 swc_core::ecma::ast::Expr::Lit(swc_core::ecma::ast::Lit::Bool(swc_core::ecma::ast::Bool {
216 span: swc_core::common::DUMMY_SP,
217 value: self,
218 }))
219 }
220}
221
222#[cfg(feature = "swc")]
223impl ToTsExpr for &bool {
224 fn to_ts_expr(self) -> swc_core::ecma::ast::Expr {
225 (*self).to_ts_expr()
226 }
227}
228
229#[cfg(feature = "swc")]
233pub fn to_ts_expr<T: ToTsExpr>(value: T) -> swc_core::ecma::ast::Expr {
234 value.to_ts_expr()
235}
236
237#[cfg(feature = "swc")]
246pub trait ToTsType {
247 fn to_ts_type(self) -> swc_core::ecma::ast::TsType;
248}
249
250#[cfg(feature = "swc")]
251impl ToTsType for swc_core::ecma::ast::TsType {
252 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
253 self
254 }
255}
256
257#[cfg(feature = "swc")]
258impl ToTsType for Box<swc_core::ecma::ast::TsType> {
259 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
260 *self
261 }
262}
263
264#[cfg(feature = "swc")]
265impl ToTsType for &swc_core::ecma::ast::TsType {
266 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
267 self.clone()
268 }
269}
270
271#[cfg(feature = "swc")]
273impl ToTsType for String {
274 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
275 swc_core::ecma::ast::TsType::TsTypeRef(swc_core::ecma::ast::TsTypeRef {
276 span: swc_core::common::DUMMY_SP,
277 type_name: swc_core::ecma::ast::TsEntityName::Ident(
278 swc_core::ecma::ast::Ident::new_no_ctxt(self.into(), swc_core::common::DUMMY_SP),
279 ),
280 type_params: None,
281 })
282 }
283}
284
285#[cfg(feature = "swc")]
286impl ToTsType for &String {
287 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
288 self.clone().to_ts_type()
289 }
290}
291
292#[cfg(feature = "swc")]
293impl ToTsType for &str {
294 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
295 self.to_string().to_ts_type()
296 }
297}
298
299#[cfg(feature = "swc")]
301impl ToTsType for swc_core::ecma::ast::Ident {
302 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
303 swc_core::ecma::ast::TsType::TsTypeRef(swc_core::ecma::ast::TsTypeRef {
304 span: swc_core::common::DUMMY_SP,
305 type_name: swc_core::ecma::ast::TsEntityName::Ident(self),
306 type_params: None,
307 })
308 }
309}
310
311#[cfg(feature = "swc")]
312impl ToTsType for &swc_core::ecma::ast::Ident {
313 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
314 self.clone().to_ts_type()
315 }
316}
317
318#[cfg(feature = "swc")]
320impl ToTsType for bool {
321 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
322 swc_core::ecma::ast::TsType::TsLitType(swc_core::ecma::ast::TsLitType {
323 span: swc_core::common::DUMMY_SP,
324 lit: swc_core::ecma::ast::TsLit::Bool(swc_core::ecma::ast::Bool {
325 span: swc_core::common::DUMMY_SP,
326 value: self,
327 }),
328 })
329 }
330}
331
332#[cfg(feature = "swc")]
333impl ToTsType for &bool {
334 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
335 (*self).to_ts_type()
336 }
337}
338
339#[cfg(feature = "swc")]
341impl ToTsType for swc_core::ecma::ast::Expr {
342 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
343 match self {
344 swc_core::ecma::ast::Expr::Ident(ident) => ident.to_ts_type(),
345 other => swc_core::ecma::ast::TsType::TsTypeQuery(swc_core::ecma::ast::TsTypeQuery {
347 span: swc_core::common::DUMMY_SP,
348 expr_name: swc_core::ecma::ast::TsTypeQueryExpr::TsEntityName(
349 swc_core::ecma::ast::TsEntityName::Ident(
350 swc_core::ecma::ast::Ident::new_no_ctxt(
351 format!("{:?}", other).into(),
352 swc_core::common::DUMMY_SP,
353 ),
354 ),
355 ),
356 type_args: None,
357 }),
358 }
359 }
360}
361
362#[cfg(feature = "swc")]
363impl ToTsType for &swc_core::ecma::ast::Expr {
364 fn to_ts_type(self) -> swc_core::ecma::ast::TsType {
365 self.clone().to_ts_type()
366 }
367}
368
369#[cfg(feature = "swc")]
373pub fn to_ts_type<T: ToTsType>(value: T) -> swc_core::ecma::ast::TsType {
374 value.to_ts_type()
375}
376
377#[cfg(feature = "swc")]
386pub trait ToTsIdent {
387 fn to_ts_ident(self) -> swc_core::ecma::ast::Ident;
388}
389
390#[cfg(feature = "swc")]
391impl ToTsIdent for swc_core::ecma::ast::Ident {
392 fn to_ts_ident(self) -> swc_core::ecma::ast::Ident {
393 self
394 }
395}
396
397#[cfg(feature = "swc")]
398impl ToTsIdent for &swc_core::ecma::ast::Ident {
399 fn to_ts_ident(self) -> swc_core::ecma::ast::Ident {
400 self.clone()
401 }
402}
403
404#[cfg(feature = "swc")]
405impl ToTsIdent for String {
406 fn to_ts_ident(self) -> swc_core::ecma::ast::Ident {
407 swc_core::ecma::ast::Ident::new_no_ctxt(self.into(), swc_core::common::DUMMY_SP)
408 }
409}
410
411#[cfg(feature = "swc")]
412impl ToTsIdent for &String {
413 fn to_ts_ident(self) -> swc_core::ecma::ast::Ident {
414 self.clone().to_ts_ident()
415 }
416}
417
418#[cfg(feature = "swc")]
419impl ToTsIdent for &str {
420 fn to_ts_ident(self) -> swc_core::ecma::ast::Ident {
421 swc_core::ecma::ast::Ident::new_no_ctxt(self.into(), swc_core::common::DUMMY_SP)
422 }
423}
424
425#[cfg(feature = "swc")]
427impl ToTsIdent for swc_core::ecma::ast::Expr {
428 fn to_ts_ident(self) -> swc_core::ecma::ast::Ident {
429 match self {
430 swc_core::ecma::ast::Expr::Ident(ident) => ident,
431 _ => swc_core::ecma::ast::Ident::new_no_ctxt(
433 "__expr__".into(),
434 swc_core::common::DUMMY_SP,
435 ),
436 }
437 }
438}
439
440#[cfg(feature = "swc")]
441impl ToTsIdent for &swc_core::ecma::ast::Expr {
442 fn to_ts_ident(self) -> swc_core::ecma::ast::Ident {
443 self.clone().to_ts_ident()
444 }
445}
446
447#[cfg(feature = "swc")]
449impl ToTsIdent for swc_core::ecma::ast::TsType {
450 fn to_ts_ident(self) -> swc_core::ecma::ast::Ident {
451 match self {
452 swc_core::ecma::ast::TsType::TsTypeRef(swc_core::ecma::ast::TsTypeRef {
453 type_name: swc_core::ecma::ast::TsEntityName::Ident(ident),
454 ..
455 }) => ident,
456 _ => swc_core::ecma::ast::Ident::new_no_ctxt(
458 "__type__".into(),
459 swc_core::common::DUMMY_SP,
460 ),
461 }
462 }
463}
464
465#[cfg(feature = "swc")]
466impl ToTsIdent for &swc_core::ecma::ast::TsType {
467 fn to_ts_ident(self) -> swc_core::ecma::ast::Ident {
468 self.clone().to_ts_ident()
469 }
470}
471
472#[cfg(feature = "swc")]
473impl ToTsIdent for Box<swc_core::ecma::ast::TsType> {
474 fn to_ts_ident(self) -> swc_core::ecma::ast::Ident {
475 (*self).to_ts_ident()
476 }
477}
478
479#[cfg(feature = "swc")]
483pub fn to_ts_ident<T: ToTsIdent>(value: T) -> swc_core::ecma::ast::Ident {
484 value.to_ts_ident()
485}
486
487#[cfg(feature = "swc")]
496pub trait ToTsStmt {
497 fn to_ts_stmt(self) -> swc_core::ecma::ast::Stmt;
498}
499
500#[cfg(feature = "swc")]
501impl ToTsStmt for swc_core::ecma::ast::Stmt {
502 fn to_ts_stmt(self) -> swc_core::ecma::ast::Stmt {
503 self
504 }
505}
506
507#[cfg(feature = "swc")]
508impl ToTsStmt for Box<swc_core::ecma::ast::Stmt> {
509 fn to_ts_stmt(self) -> swc_core::ecma::ast::Stmt {
510 *self
511 }
512}
513
514#[cfg(feature = "swc")]
515impl ToTsStmt for &swc_core::ecma::ast::Stmt {
516 fn to_ts_stmt(self) -> swc_core::ecma::ast::Stmt {
517 self.clone()
518 }
519}
520
521#[cfg(feature = "swc")]
523impl ToTsStmt for swc_core::ecma::ast::Expr {
524 fn to_ts_stmt(self) -> swc_core::ecma::ast::Stmt {
525 swc_core::ecma::ast::Stmt::Expr(swc_core::ecma::ast::ExprStmt {
526 span: swc_core::common::DUMMY_SP,
527 expr: Box::new(self),
528 })
529 }
530}
531
532#[cfg(feature = "swc")]
533impl ToTsStmt for Box<swc_core::ecma::ast::Expr> {
534 fn to_ts_stmt(self) -> swc_core::ecma::ast::Stmt {
535 swc_core::ecma::ast::Stmt::Expr(swc_core::ecma::ast::ExprStmt {
536 span: swc_core::common::DUMMY_SP,
537 expr: self,
538 })
539 }
540}
541
542#[cfg(feature = "swc")]
543impl ToTsStmt for String {
544 fn to_ts_stmt(self) -> swc_core::ecma::ast::Stmt {
545 use swc_core::ecma::ast::{BlockStmt, EmptyStmt, ModuleItem, Stmt};
546
547 let mut stmts: Vec<Stmt> = parse_ts_to_module_items(&self)
548 .into_iter()
549 .filter_map(|item| match item {
550 ModuleItem::Stmt(stmt) => Some(stmt),
551 _ => None,
552 })
553 .collect();
554
555 match stmts.len() {
556 0 => Stmt::Empty(EmptyStmt {
557 span: swc_core::common::DUMMY_SP,
558 }),
559 1 => stmts.pop().expect("single statement missing"),
560 _ => Stmt::Block(BlockStmt {
561 span: swc_core::common::DUMMY_SP,
562 ctxt: swc_core::common::SyntaxContext::empty(),
563 stmts,
564 }),
565 }
566 }
567}
568
569#[cfg(feature = "swc")]
570impl ToTsStmt for &String {
571 fn to_ts_stmt(self) -> swc_core::ecma::ast::Stmt {
572 self.as_str().to_ts_stmt()
573 }
574}
575
576#[cfg(feature = "swc")]
577impl ToTsStmt for &str {
578 fn to_ts_stmt(self) -> swc_core::ecma::ast::Stmt {
579 self.to_string().to_ts_stmt()
580 }
581}
582
583#[cfg(feature = "swc")]
587pub fn to_ts_stmt<T: ToTsStmt>(value: T) -> swc_core::ecma::ast::Stmt {
588 value.to_ts_stmt()
589}
590
591#[cfg(feature = "swc")]
598pub trait ToTsTypeName {
599 fn to_ts_type_name(&self) -> String;
600}
601
602#[cfg(feature = "swc")]
603impl ToTsTypeName for swc_core::ecma::ast::Ident {
604 fn to_ts_type_name(&self) -> String {
605 self.sym.to_string()
606 }
607}
608
609#[cfg(feature = "swc")]
610impl ToTsTypeName for &swc_core::ecma::ast::Ident {
611 fn to_ts_type_name(&self) -> String {
612 self.sym.to_string()
613 }
614}
615
616#[cfg(feature = "swc")]
617impl ToTsTypeName for String {
618 fn to_ts_type_name(&self) -> String {
619 self.clone()
620 }
621}
622
623#[cfg(feature = "swc")]
624impl ToTsTypeName for &String {
625 fn to_ts_type_name(&self) -> String {
626 (*self).clone()
627 }
628}
629
630#[cfg(feature = "swc")]
631impl ToTsTypeName for &str {
632 fn to_ts_type_name(&self) -> String {
633 (*self).to_string()
634 }
635}
636
637#[cfg(feature = "swc")]
672#[macro_export]
673macro_rules! ts_ident {
674 ($name:expr) => {
677 $crate::swc_core::ecma::ast::Ident::new_no_ctxt(
678 AsRef::<str>::as_ref(&$name).into(),
679 $crate::swc_core::common::DUMMY_SP,
680 )
681 };
682 ($fmt:expr, $($args:expr),+ $(,)?) => {
684 $crate::swc_core::ecma::ast::Ident::new_no_ctxt(format!($fmt, $($args),+).into(), $crate::swc_core::common::DUMMY_SP)
685 };
686}
687
688#[cfg(feature = "swc")]
718#[macro_export]
719macro_rules! ts_private_ident {
720 ($name:expr) => {{
721 let mark = $crate::swc_core::common::Mark::fresh($crate::swc_core::common::Mark::root());
722 $crate::swc_core::ecma::ast::Ident::new(
723 $name.into(),
724 $crate::swc_core::common::DUMMY_SP,
725 $crate::swc_core::common::SyntaxContext::empty().apply_mark(mark),
726 )
727 }};
728}
729
730#[cfg(feature = "swc")]
762#[macro_export]
763macro_rules! stmt_block {
764 ($stmts:expr) => {
765 $crate::swc_core::ecma::ast::Stmt::Block($crate::swc_core::ecma::ast::BlockStmt {
766 span: $crate::swc_core::common::DUMMY_SP,
767 ctxt: $crate::swc_core::common::SyntaxContext::empty(),
768 stmts: $stmts,
769 })
770 };
771}
772
773#[cfg(feature = "swc")]
793pub struct StmtVec(pub Vec<swc_core::ecma::ast::Stmt>);
794
795#[cfg(feature = "swc")]
815#[macro_export]
816macro_rules! stmt_vec {
817 ($stmts:expr) => {
818 macroforge_ts_syn::StmtVec($stmts)
819 };
820}
821
822#[cfg(feature = "swc")]
845#[macro_export]
846macro_rules! stmt_block_from_vec {
847 ($stmts:expr) => {
848 $crate::swc_core::ecma::ast::Stmt::Block($crate::swc_core::ecma::ast::BlockStmt {
849 span: $crate::swc_core::common::DUMMY_SP,
850 ctxt: $crate::swc_core::common::SyntaxContext::empty(),
851 stmts: $stmts,
852 })
853 };
854}
855
856#[cfg(feature = "swc")]
902#[macro_export]
903macro_rules! fn_expr {
904 ($body_stmts:expr) => {
905 $crate::swc_core::ecma::ast::Expr::Fn($crate::swc_core::ecma::ast::FnExpr {
906 ident: None,
907 function: Box::new($crate::swc_core::ecma::ast::Function {
908 params: vec![],
909 decorators: vec![],
910 span: $crate::swc_core::common::DUMMY_SP,
911 ctxt: $crate::swc_core::common::SyntaxContext::empty(),
912 body: Some($crate::swc_core::ecma::ast::BlockStmt {
913 span: $crate::swc_core::common::DUMMY_SP,
914 ctxt: $crate::swc_core::common::SyntaxContext::empty(),
915 stmts: $body_stmts,
916 }),
917 is_generator: false,
918 is_async: false,
919 type_params: None,
920 return_type: None,
921 }),
922 })
923 };
924 ($params:expr, $body_stmts:expr) => {
925 $crate::swc_core::ecma::ast::Expr::Fn($crate::swc_core::ecma::ast::FnExpr {
926 ident: None,
927 function: Box::new($crate::swc_core::ecma::ast::Function {
928 params: $params,
929 decorators: vec![],
930 span: $crate::swc_core::common::DUMMY_SP,
931 ctxt: $crate::swc_core::common::SyntaxContext::empty(),
932 body: Some($crate::swc_core::ecma::ast::BlockStmt {
933 span: $crate::swc_core::common::DUMMY_SP,
934 ctxt: $crate::swc_core::common::SyntaxContext::empty(),
935 stmts: $body_stmts,
936 }),
937 is_generator: false,
938 is_async: false,
939 type_params: None,
940 return_type: None,
941 }),
942 })
943 };
944}
945
946#[cfg(feature = "swc")]
992#[macro_export]
993macro_rules! member_expr {
994 ($obj:expr, $prop:expr) => {
995 $crate::swc_core::ecma::ast::Expr::Member($crate::swc_core::ecma::ast::MemberExpr {
996 span: $crate::swc_core::common::DUMMY_SP,
997 obj: Box::new($obj),
998 prop: $crate::swc_core::ecma::ast::MemberProp::Ident(
999 $crate::swc_core::ecma::ast::IdentName {
1000 span: $crate::swc_core::common::DUMMY_SP,
1001 sym: $prop.into(),
1002 },
1003 ),
1004 })
1005 };
1006}
1007
1008#[cfg(feature = "swc")]
1051#[macro_export]
1052macro_rules! assign_stmt {
1053 ($lhs:expr, $rhs:expr) => {
1054 $crate::swc_core::ecma::ast::Stmt::Expr($crate::swc_core::ecma::ast::ExprStmt {
1055 span: $crate::swc_core::common::DUMMY_SP,
1056 expr: Box::new($crate::swc_core::ecma::ast::Expr::Assign(
1057 $crate::swc_core::ecma::ast::AssignExpr {
1058 span: $crate::swc_core::common::DUMMY_SP,
1059 op: $crate::swc_core::ecma::ast::AssignOp::Assign,
1060 left: $lhs,
1061 right: Box::new($rhs),
1062 },
1063 )),
1064 })
1065 };
1066}
1067
1068#[cfg(feature = "swc")]
1126#[macro_export]
1127macro_rules! fn_assign {
1128 ($obj:expr, $prop:expr, $body_stmts:expr) => {{
1129 use $crate::swc_core::common::{DUMMY_SP, SyntaxContext};
1130 use $crate::swc_core::ecma::ast::*;
1131
1132 Stmt::Expr(ExprStmt {
1133 span: DUMMY_SP,
1134 expr: Box::new(Expr::Assign(AssignExpr {
1135 span: DUMMY_SP,
1136 op: AssignOp::Assign,
1137 left: AssignTarget::Simple(SimpleAssignTarget::Member(MemberExpr {
1138 span: DUMMY_SP,
1139 obj: Box::new($obj),
1140 prop: MemberProp::Ident(IdentName {
1141 span: DUMMY_SP,
1142 sym: $prop.into(),
1143 }),
1144 })),
1145 right: Box::new(Expr::Fn(FnExpr {
1146 ident: None,
1147 function: Box::new(Function {
1148 params: vec![],
1149 decorators: vec![],
1150 span: DUMMY_SP,
1151 ctxt: SyntaxContext::empty(),
1152 body: Some(BlockStmt {
1153 span: DUMMY_SP,
1154 ctxt: SyntaxContext::empty(),
1155 stmts: $body_stmts,
1156 }),
1157 is_generator: false,
1158 is_async: false,
1159 type_params: None,
1160 return_type: None,
1161 }),
1162 })),
1163 })),
1164 })
1165 }};
1166 ($obj:expr, $prop:expr, $params:expr, $body_stmts:expr) => {{
1167 use $crate::swc_core::common::{DUMMY_SP, SyntaxContext};
1168 use $crate::swc_core::ecma::ast::*;
1169
1170 Stmt::Expr(ExprStmt {
1171 span: DUMMY_SP,
1172 expr: Box::new(Expr::Assign(AssignExpr {
1173 span: DUMMY_SP,
1174 op: AssignOp::Assign,
1175 left: AssignTarget::Simple(SimpleAssignTarget::Member(MemberExpr {
1176 span: DUMMY_SP,
1177 obj: Box::new($obj),
1178 prop: MemberProp::Ident(IdentName {
1179 span: DUMMY_SP,
1180 sym: $prop.into(),
1181 }),
1182 })),
1183 right: Box::new(Expr::Fn(FnExpr {
1184 ident: None,
1185 function: Box::new(Function {
1186 params: $params,
1187 decorators: vec![],
1188 span: DUMMY_SP,
1189 ctxt: SyntaxContext::empty(),
1190 body: Some(BlockStmt {
1191 span: DUMMY_SP,
1192 ctxt: SyntaxContext::empty(),
1193 stmts: $body_stmts,
1194 }),
1195 is_generator: false,
1196 is_async: false,
1197 type_params: None,
1198 return_type: None,
1199 }),
1200 })),
1201 })),
1202 })
1203 }};
1204}
1205
1206#[cfg(feature = "swc")]
1215pub fn expr_to_string(expr: &swc_core::ecma::ast::Expr) -> String {
1216 use swc_core::common::sync::Lrc;
1217 use swc_core::ecma::ast::{ExprStmt, Module, ModuleItem, Stmt};
1218 use swc_core::ecma::codegen::{Config, Emitter, text_writer::JsWriter};
1219
1220 let module = Module {
1222 span: swc_core::common::DUMMY_SP,
1223 body: vec![ModuleItem::Stmt(Stmt::Expr(ExprStmt {
1224 span: swc_core::common::DUMMY_SP,
1225 expr: Box::new(expr.clone()),
1226 }))],
1227 shebang: None,
1228 };
1229
1230 let cm = Lrc::new(swc_core::common::SourceMap::default());
1231 let mut buf = Vec::new();
1232 {
1233 let mut emitter = Emitter {
1234 cfg: Config::default(),
1235 cm: cm.clone(),
1236 comments: None,
1237 wr: JsWriter::new(cm.clone(), "\n", &mut buf, None),
1238 };
1239 let _ = emitter.emit_module(&module);
1240 }
1241 let s = String::from_utf8(buf).unwrap_or_default();
1243 s.trim_end().trim_end_matches(';').to_string()
1244}
1245
1246#[cfg(feature = "swc")]
1248pub fn type_to_string(ty: &swc_core::ecma::ast::TsType) -> String {
1249 use swc_core::common::sync::Lrc;
1250 use swc_core::ecma::ast::*;
1251 use swc_core::ecma::codegen::{Config, Emitter, text_writer::JsWriter};
1252
1253 let module = Module {
1255 span: swc_core::common::DUMMY_SP,
1256 body: vec![ModuleItem::Stmt(Stmt::Decl(Decl::TsTypeAlias(Box::new(
1257 TsTypeAliasDecl {
1258 span: swc_core::common::DUMMY_SP,
1259 declare: false,
1260 id: Ident::new_no_ctxt("__T".into(), swc_core::common::DUMMY_SP),
1261 type_params: None,
1262 type_ann: Box::new(ty.clone()),
1263 },
1264 ))))],
1265 shebang: None,
1266 };
1267
1268 let cm = Lrc::new(swc_core::common::SourceMap::default());
1269 let mut buf = Vec::new();
1270 {
1271 let mut emitter = Emitter {
1272 cfg: Config::default(),
1273 cm: cm.clone(),
1274 comments: None,
1275 wr: JsWriter::new(cm.clone(), "\n", &mut buf, None),
1276 };
1277 let _ = emitter.emit_module(&module);
1278 }
1279 let s = String::from_utf8(buf).unwrap_or_default();
1281 if let Some(eq_pos) = s.find("= ") {
1283 let after_eq = &s[eq_pos + 2..];
1284 if let Some(semi_pos) = after_eq.rfind(';') {
1285 return after_eq[..semi_pos].to_string();
1286 }
1287 }
1288 s.trim().to_string()
1289}
1290
1291#[cfg(feature = "swc")]
1293pub fn ident_to_string(ident: &swc_core::ecma::ast::Ident) -> String {
1294 ident.sym.to_string()
1295}
1296
1297#[cfg(feature = "swc")]
1314pub fn emit_module_items(
1315 items: &[swc_core::ecma::ast::ModuleItem],
1316 comments: &swc_core::common::comments::SingleThreadedComments,
1317) -> String {
1318 use swc_core::common::sync::Lrc;
1319 use swc_core::ecma::ast::Module;
1320 use swc_core::ecma::codegen::{Config, Emitter, text_writer::JsWriter};
1321
1322 let module = Module {
1323 span: swc_core::common::DUMMY_SP,
1324 body: items.to_vec(),
1325 shebang: None,
1326 };
1327
1328 let cm = Lrc::new(swc_core::common::SourceMap::default());
1329 let mut buf = Vec::new();
1330 {
1331 let mut emitter = Emitter {
1332 cfg: Config::default().with_minify(false),
1333 cm: cm.clone(),
1334 comments: Some(comments),
1335 wr: JsWriter::new(cm.clone(), "\n", &mut buf, None),
1336 };
1337 let _ = emitter.emit_module(&module);
1338 }
1339 String::from_utf8(buf).unwrap_or_default()
1340}
1341
1342#[cfg(feature = "swc")]
1346pub fn emit_expr(expr: &swc_core::ecma::ast::Expr) -> String {
1347 use swc_core::common::comments::SingleThreadedComments;
1348 use swc_core::common::sync::Lrc;
1349 use swc_core::ecma::ast::{ExprStmt, Module, ModuleItem, Stmt};
1350 use swc_core::ecma::codegen::{Config, Emitter, text_writer::JsWriter};
1351
1352 let module = Module {
1354 span: swc_core::common::DUMMY_SP,
1355 body: vec![ModuleItem::Stmt(Stmt::Expr(ExprStmt {
1356 span: swc_core::common::DUMMY_SP,
1357 expr: Box::new(expr.clone()),
1358 }))],
1359 shebang: None,
1360 };
1361
1362 let cm = Lrc::new(swc_core::common::SourceMap::default());
1363 let comments = SingleThreadedComments::default();
1364 let mut buf = Vec::new();
1365 {
1366 let mut emitter = Emitter {
1367 cfg: Config::default().with_minify(false),
1368 cm: cm.clone(),
1369 comments: Some(&comments),
1370 wr: JsWriter::new(cm.clone(), "\n", &mut buf, None),
1371 };
1372 let _ = emitter.emit_module(&module);
1373 }
1374 let s = String::from_utf8(buf).unwrap_or_default();
1376 s.trim_end().trim_end_matches(';').to_string()
1377}
1378
1379#[cfg(feature = "swc")]
1383pub fn emit_ts_type(ty: &swc_core::ecma::ast::TsType) -> String {
1384 use swc_core::common::comments::SingleThreadedComments;
1385 use swc_core::common::sync::Lrc;
1386 use swc_core::ecma::ast::{Decl, Ident, Module, ModuleItem, Stmt, TsTypeAliasDecl};
1387 use swc_core::ecma::codegen::{Config, Emitter, text_writer::JsWriter};
1388
1389 let module = Module {
1391 span: swc_core::common::DUMMY_SP,
1392 body: vec![ModuleItem::Stmt(Stmt::Decl(Decl::TsTypeAlias(Box::new(
1393 TsTypeAliasDecl {
1394 span: swc_core::common::DUMMY_SP,
1395 declare: false,
1396 id: Ident::new("__T".into(), swc_core::common::DUMMY_SP, Default::default()),
1397 type_params: None,
1398 type_ann: Box::new(ty.clone()),
1399 },
1400 ))))],
1401 shebang: None,
1402 };
1403
1404 let cm = Lrc::new(swc_core::common::SourceMap::default());
1405 let comments = SingleThreadedComments::default();
1406 let mut buf = Vec::new();
1407 {
1408 let mut emitter = Emitter {
1409 cfg: Config::default().with_minify(false),
1410 cm: cm.clone(),
1411 comments: Some(&comments),
1412 wr: JsWriter::new(cm.clone(), "\n", &mut buf, None),
1413 };
1414 let _ = emitter.emit_module(&module);
1415 }
1416 let s = String::from_utf8(buf).unwrap_or_default();
1417 if let Some(start) = s.find('=') {
1419 let after_eq = &s[start + 1..];
1420 after_eq.trim().trim_end_matches(';').to_string()
1421 } else {
1422 s
1423 }
1424}
1425
1426#[cfg(feature = "swc")]
1430pub fn emit_stmt(stmt: &swc_core::ecma::ast::Stmt) -> String {
1431 use swc_core::common::comments::SingleThreadedComments;
1432 use swc_core::common::sync::Lrc;
1433 use swc_core::ecma::ast::{Module, ModuleItem};
1434 use swc_core::ecma::codegen::{Config, Emitter, text_writer::JsWriter};
1435
1436 let module = Module {
1437 span: swc_core::common::DUMMY_SP,
1438 body: vec![ModuleItem::Stmt(stmt.clone())],
1439 shebang: None,
1440 };
1441
1442 let cm = Lrc::new(swc_core::common::SourceMap::default());
1443 let comments = SingleThreadedComments::default();
1444 let mut buf = Vec::new();
1445 {
1446 let mut emitter = Emitter {
1447 cfg: Config::default().with_minify(false),
1448 cm: cm.clone(),
1449 comments: Some(&comments),
1450 wr: JsWriter::new(cm.clone(), "\n", &mut buf, None),
1451 };
1452 let _ = emitter.emit_module(&module);
1453 }
1454 String::from_utf8(buf).unwrap_or_default()
1455}
1456
1457pub trait ToTsString {
1473 fn to_ts_string(&self) -> String;
1475}
1476
1477impl ToTsString for String {
1481 fn to_ts_string(&self) -> String {
1482 self.clone()
1483 }
1484}
1485
1486impl ToTsString for str {
1487 fn to_ts_string(&self) -> String {
1488 self.to_owned()
1489 }
1490}
1491
1492impl ToTsString for bool {
1493 fn to_ts_string(&self) -> String {
1494 self.to_string()
1495 }
1496}
1497
1498impl ToTsString for i8 {
1499 fn to_ts_string(&self) -> String {
1500 self.to_string()
1501 }
1502}
1503
1504impl ToTsString for i16 {
1505 fn to_ts_string(&self) -> String {
1506 self.to_string()
1507 }
1508}
1509
1510impl ToTsString for i32 {
1511 fn to_ts_string(&self) -> String {
1512 self.to_string()
1513 }
1514}
1515
1516impl ToTsString for i64 {
1517 fn to_ts_string(&self) -> String {
1518 self.to_string()
1519 }
1520}
1521
1522impl ToTsString for i128 {
1523 fn to_ts_string(&self) -> String {
1524 self.to_string()
1525 }
1526}
1527
1528impl ToTsString for isize {
1529 fn to_ts_string(&self) -> String {
1530 self.to_string()
1531 }
1532}
1533
1534impl ToTsString for u8 {
1535 fn to_ts_string(&self) -> String {
1536 self.to_string()
1537 }
1538}
1539
1540impl ToTsString for u16 {
1541 fn to_ts_string(&self) -> String {
1542 self.to_string()
1543 }
1544}
1545
1546impl ToTsString for u32 {
1547 fn to_ts_string(&self) -> String {
1548 self.to_string()
1549 }
1550}
1551
1552impl ToTsString for u64 {
1553 fn to_ts_string(&self) -> String {
1554 self.to_string()
1555 }
1556}
1557
1558impl ToTsString for u128 {
1559 fn to_ts_string(&self) -> String {
1560 self.to_string()
1561 }
1562}
1563
1564impl ToTsString for usize {
1565 fn to_ts_string(&self) -> String {
1566 self.to_string()
1567 }
1568}
1569
1570impl ToTsString for f32 {
1571 fn to_ts_string(&self) -> String {
1572 self.to_string()
1573 }
1574}
1575
1576impl ToTsString for f64 {
1577 fn to_ts_string(&self) -> String {
1578 self.to_string()
1579 }
1580}
1581
1582impl ToTsString for char {
1583 fn to_ts_string(&self) -> String {
1584 self.to_string()
1585 }
1586}
1587
1588#[cfg(feature = "swc")]
1590impl ToTsString for swc_core::ecma::ast::Expr {
1591 fn to_ts_string(&self) -> String {
1592 emit_expr(self)
1593 }
1594}
1595
1596#[cfg(feature = "swc")]
1597impl ToTsString for swc_core::ecma::ast::Ident {
1598 fn to_ts_string(&self) -> String {
1599 self.sym.to_string()
1600 }
1601}
1602
1603#[cfg(feature = "swc")]
1604impl ToTsString for swc_core::ecma::ast::TsType {
1605 fn to_ts_string(&self) -> String {
1606 emit_ts_type(self)
1607 }
1608}
1609
1610#[cfg(feature = "swc")]
1611impl ToTsString for swc_core::ecma::ast::Stmt {
1612 fn to_ts_string(&self) -> String {
1613 emit_stmt(self)
1614 }
1615}
1616
1617#[cfg(feature = "swc")]
1618impl ToTsString for crate::TsStream {
1619 fn to_ts_string(&self) -> String {
1620 self.source().to_string()
1621 }
1622}
1623
1624impl<T: ToTsString + ?Sized> ToTsString for &T {
1626 fn to_ts_string(&self) -> String {
1627 (*self).to_ts_string()
1628 }
1629}
1630
1631impl<T: ToTsString + ?Sized> ToTsString for &mut T {
1632 fn to_ts_string(&self) -> String {
1633 (**self).to_ts_string()
1634 }
1635}
1636
1637impl<T: ToTsString + ?Sized> ToTsString for Box<T> {
1638 fn to_ts_string(&self) -> String {
1639 (**self).to_ts_string()
1640 }
1641}
1642
1643impl<T: ToTsString + Clone> ToTsString for std::borrow::Cow<'_, T> {
1644 fn to_ts_string(&self) -> String {
1645 self.as_ref().to_ts_string()
1646 }
1647}
1648
1649impl<T: ToTsString> ToTsString for std::rc::Rc<T> {
1650 fn to_ts_string(&self) -> String {
1651 (**self).to_ts_string()
1652 }
1653}
1654
1655impl<T: ToTsString> ToTsString for std::sync::Arc<T> {
1656 fn to_ts_string(&self) -> String {
1657 (**self).to_ts_string()
1658 }
1659}
1660
1661#[cfg(feature = "swc")]
1675#[derive(Debug, Clone)]
1676pub struct TsExpr(pub swc_core::ecma::ast::Expr);
1677
1678#[cfg(feature = "swc")]
1679impl std::fmt::Display for TsExpr {
1680 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1681 write!(f, "{}", emit_expr(&self.0))
1682 }
1683}
1684
1685#[cfg(feature = "swc")]
1686impl From<swc_core::ecma::ast::Expr> for TsExpr {
1687 fn from(expr: swc_core::ecma::ast::Expr) -> Self {
1688 TsExpr(expr)
1689 }
1690}
1691
1692#[cfg(feature = "swc")]
1693impl std::ops::Deref for TsExpr {
1694 type Target = swc_core::ecma::ast::Expr;
1695 fn deref(&self) -> &Self::Target {
1696 &self.0
1697 }
1698}
1699
1700#[cfg(feature = "swc")]
1713#[derive(Debug, Clone)]
1714pub struct TsIdent(pub swc_core::ecma::ast::Ident);
1715
1716#[cfg(feature = "swc")]
1717impl std::fmt::Display for TsIdent {
1718 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1719 write!(f, "{}", self.0.sym)
1720 }
1721}
1722
1723#[cfg(feature = "swc")]
1724impl From<swc_core::ecma::ast::Ident> for TsIdent {
1725 fn from(ident: swc_core::ecma::ast::Ident) -> Self {
1726 TsIdent(ident)
1727 }
1728}
1729
1730#[cfg(feature = "swc")]
1731impl std::ops::Deref for TsIdent {
1732 type Target = swc_core::ecma::ast::Ident;
1733 fn deref(&self) -> &Self::Target {
1734 &self.0
1735 }
1736}
1737
1738#[cfg(feature = "swc")]
1751#[derive(Debug, Clone)]
1752pub struct TsTypeWrapper(pub swc_core::ecma::ast::TsType);
1753
1754#[cfg(feature = "swc")]
1755impl std::fmt::Display for TsTypeWrapper {
1756 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1757 write!(f, "{}", emit_ts_type(&self.0))
1758 }
1759}
1760
1761#[cfg(feature = "swc")]
1762impl From<swc_core::ecma::ast::TsType> for TsTypeWrapper {
1763 fn from(ty: swc_core::ecma::ast::TsType) -> Self {
1764 TsTypeWrapper(ty)
1765 }
1766}
1767
1768#[cfg(feature = "swc")]
1769impl std::ops::Deref for TsTypeWrapper {
1770 type Target = swc_core::ecma::ast::TsType;
1771 fn deref(&self) -> &Self::Target {
1772 &self.0
1773 }
1774}
1775
1776#[cfg(feature = "swc")]
1789#[derive(Debug, Clone)]
1790pub struct TsStmt(pub swc_core::ecma::ast::Stmt);
1791
1792#[cfg(feature = "swc")]
1793impl std::fmt::Display for TsStmt {
1794 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1795 write!(f, "{}", emit_stmt(&self.0))
1796 }
1797}
1798
1799#[cfg(feature = "swc")]
1800impl From<swc_core::ecma::ast::Stmt> for TsStmt {
1801 fn from(stmt: swc_core::ecma::ast::Stmt) -> Self {
1802 TsStmt(stmt)
1803 }
1804}
1805
1806#[cfg(feature = "swc")]
1807impl std::ops::Deref for TsStmt {
1808 type Target = swc_core::ecma::ast::Stmt;
1809 fn deref(&self) -> &Self::Target {
1810 &self.0
1811 }
1812}
1813
1814#[cfg(feature = "swc")]
1827pub mod __internal {
1828 use std::collections::HashMap;
1829 use swc_core::ecma::ast::*;
1830 use swc_core::ecma::visit::{VisitMut, VisitMutWith};
1831
1832 #[derive(Debug, Clone)]
1842 pub enum ContextCollector {
1843 ObjectProps(Vec<PropOrSpread>),
1845 ArrayElems(Vec<ExprOrSpread>),
1847 ClassMembers(Vec<ClassMember>),
1849 TypeProps(Vec<TsTypeElement>),
1851 Stmts(Vec<Stmt>),
1853 }
1854
1855 impl ContextCollector {
1856 pub fn new(context_type: u8) -> Self {
1860 match context_type {
1861 0 => Self::ObjectProps(vec![]),
1862 1 => Self::ArrayElems(vec![]),
1863 2 => Self::ClassMembers(vec![]),
1864 3 => Self::TypeProps(vec![]),
1865 _ => Self::Stmts(vec![]),
1866 }
1867 }
1868
1869 pub fn for_object() -> Self {
1871 Self::ObjectProps(vec![])
1872 }
1873
1874 pub fn for_array() -> Self {
1876 Self::ArrayElems(vec![])
1877 }
1878
1879 pub fn for_class() -> Self {
1881 Self::ClassMembers(vec![])
1882 }
1883
1884 pub fn for_type_object() -> Self {
1886 Self::TypeProps(vec![])
1887 }
1888 }
1889
1890 pub fn push_object_prop(collector: &mut ContextCollector, prop: PropOrSpread) {
1894 match collector {
1895 ContextCollector::ObjectProps(props) => props.push(prop),
1896 _ => panic!("push_object_prop called on non-ObjectProps collector"),
1897 }
1898 }
1899
1900 pub fn push_array_elem(collector: &mut ContextCollector, elem: ExprOrSpread) {
1904 match collector {
1905 ContextCollector::ArrayElems(elems) => elems.push(elem),
1906 _ => panic!("push_array_elem called on non-ArrayElems collector"),
1907 }
1908 }
1909
1910 pub fn push_class_member(collector: &mut ContextCollector, member: ClassMember) {
1914 match collector {
1915 ContextCollector::ClassMembers(members) => members.push(member),
1916 _ => panic!("push_class_member called on non-ClassMembers collector"),
1917 }
1918 }
1919
1920 pub fn push_type_prop(collector: &mut ContextCollector, prop: TsTypeElement) {
1924 match collector {
1925 ContextCollector::TypeProps(props) => props.push(prop),
1926 _ => panic!("push_type_prop called on non-TypeProps collector"),
1927 }
1928 }
1929
1930 pub fn extract_prop_from_wrapped_expr(expr: &Expr) -> Option<PropOrSpread> {
1936 if let Expr::Paren(ParenExpr { expr: inner, .. }) = expr
1938 && let Expr::Object(ObjectLit { props, .. }) = inner.as_ref()
1939 {
1940 for prop in props {
1942 match prop {
1943 PropOrSpread::Prop(p) => {
1944 if let Prop::KeyValue(KeyValueProp {
1945 key: PropName::Ident(ident),
1946 ..
1947 }) = p.as_ref()
1948 && ident.sym.as_ref() == "__mf_dummy"
1949 {
1950 continue;
1951 }
1952 return Some(prop.clone());
1953 }
1954 PropOrSpread::Spread(_) => return Some(prop.clone()),
1955 }
1956 }
1957 }
1958 None
1959 }
1960
1961 pub fn extract_elem_from_wrapped_expr(expr: &Expr) -> Option<ExprOrSpread> {
1965 if let Expr::Array(ArrayLit { elems, .. }) = expr
1967 && let Some(elem) = elems.iter().flatten().next()
1968 {
1969 return Some(elem.clone());
1970 }
1971 None
1972 }
1973
1974 pub fn extract_class_members_from_wrapped(item: &ModuleItem) -> Vec<ClassMember> {
1978 if let ModuleItem::Stmt(Stmt::Decl(Decl::Class(ClassDecl { class, .. }))) = item {
1980 return class.body.clone();
1981 }
1982 vec![]
1983 }
1984
1985 pub fn extract_type_elements_from_wrapped(item: &ModuleItem) -> Vec<TsTypeElement> {
1989 if let ModuleItem::Stmt(Stmt::Decl(Decl::TsTypeAlias(type_alias))) = item
1991 && let TsType::TsTypeLit(type_lit) = type_alias.type_ann.as_ref()
1992 {
1993 return type_lit.members.clone();
1994 }
1995 vec![]
1996 }
1997
1998 pub fn merge_object_props(item: &mut ModuleItem, props: Vec<PropOrSpread>) {
2003 let mut merger = ObjectPropMerger {
2004 props_to_add: props,
2005 };
2006 item.visit_mut_with(&mut merger);
2007 }
2008
2009 pub fn merge_array_elems(item: &mut ModuleItem, elems: Vec<ExprOrSpread>) {
2011 let mut merger = ArrayElemMerger {
2012 elems_to_add: elems,
2013 };
2014 item.visit_mut_with(&mut merger);
2015 }
2016
2017 pub fn merge_class_members(item: &mut ModuleItem, members: Vec<ClassMember>) {
2019 let mut merger = ClassMemberMerger {
2020 members_to_add: members,
2021 };
2022 item.visit_mut_with(&mut merger);
2023 }
2024
2025 pub fn merge_type_props(item: &mut ModuleItem, props: Vec<TsTypeElement>) {
2027 let mut merger = TypePropMerger {
2028 props_to_add: props,
2029 };
2030 item.visit_mut_with(&mut merger);
2031 }
2032
2033 struct ObjectPropMerger {
2035 props_to_add: Vec<PropOrSpread>,
2036 }
2037
2038 impl VisitMut for ObjectPropMerger {
2039 fn visit_mut_object_lit(&mut self, obj: &mut ObjectLit) {
2040 if !self.props_to_add.is_empty() {
2041 obj.props.retain(|prop| {
2043 if let PropOrSpread::Prop(p) = prop
2044 && let Prop::KeyValue(KeyValueProp {
2045 key: PropName::Ident(ident),
2046 ..
2047 }) = p.as_ref()
2048 && ident.sym.as_ref() == "__mf_dummy"
2049 {
2050 return false;
2051 }
2052 true
2053 });
2054 obj.props.extend(std::mem::take(&mut self.props_to_add));
2056 }
2057 }
2058 }
2059
2060 struct ArrayElemMerger {
2062 elems_to_add: Vec<ExprOrSpread>,
2063 }
2064
2065 impl VisitMut for ArrayElemMerger {
2066 fn visit_mut_array_lit(&mut self, arr: &mut ArrayLit) {
2067 if !self.elems_to_add.is_empty() {
2068 if let Some(Some(ExprOrSpread { expr, .. })) = arr.elems.first()
2070 && let Expr::Lit(Lit::Num(Number { value, .. })) = expr.as_ref()
2071 && *value == 0.0
2072 {
2073 arr.elems.remove(0);
2074 }
2075 for elem in std::mem::take(&mut self.elems_to_add) {
2077 arr.elems.push(Some(elem));
2078 }
2079 }
2080 }
2081 }
2082
2083 struct ClassMemberMerger {
2085 members_to_add: Vec<ClassMember>,
2086 }
2087
2088 impl VisitMut for ClassMemberMerger {
2089 fn visit_mut_class(&mut self, class: &mut Class) {
2090 if !self.members_to_add.is_empty() {
2091 class.body.extend(std::mem::take(&mut self.members_to_add));
2092 }
2093 }
2094 }
2095
2096 struct TypePropMerger {
2098 props_to_add: Vec<TsTypeElement>,
2099 }
2100
2101 impl VisitMut for TypePropMerger {
2102 fn visit_mut_ts_type_lit(&mut self, lit: &mut TsTypeLit) {
2103 if !self.props_to_add.is_empty() {
2104 lit.members.extend(std::mem::take(&mut self.props_to_add));
2105 }
2106 }
2107 }
2108
2109 struct TypeReplacer {
2115 replacements: HashMap<String, TsType>,
2117 }
2118
2119 impl VisitMut for TypeReplacer {
2120 fn visit_mut_ts_type(&mut self, ty: &mut TsType) {
2121 if let TsType::TsTypeRef(TsTypeRef {
2123 type_name: TsEntityName::Ident(ident),
2124 type_params: None,
2125 ..
2126 }) = ty
2127 {
2128 let name = ident.sym.to_string();
2129 if let Some(replacement) = self.replacements.get(&name) {
2130 *ty = replacement.clone();
2131 return;
2132 }
2133 }
2134 ty.visit_mut_children_with(self);
2136 }
2137 }
2138
2139 pub fn replace_type_markers(item: &mut ModuleItem, replacements: HashMap<String, TsType>) {
2149 let mut replacer = TypeReplacer { replacements };
2150 item.visit_mut_with(&mut replacer);
2151 }
2152
2153 pub fn replace_type_markers_stmt(stmt: &mut Stmt, replacements: HashMap<String, TsType>) {
2155 let mut replacer = TypeReplacer { replacements };
2156 stmt.visit_mut_with(&mut replacer);
2157 }
2158
2159 pub fn push_opener(item: ModuleItem, output: &mut Vec<ModuleItem>, _depth: usize) -> usize {
2173 let idx = output.len();
2174 output.push(item);
2175 idx
2176 }
2177
2178 pub fn finalize_closer(item: ModuleItem, output: &mut Vec<ModuleItem>, opener_idx: usize) {
2190 let closer_stmts = extract_function_body_statements(&item);
2192
2193 let intermediate_items: Vec<ModuleItem> = output.drain((opener_idx + 1)..).collect();
2195
2196 let intermediate_stmts: Vec<Stmt> = intermediate_items
2198 .into_iter()
2199 .filter_map(|mi| match mi {
2200 ModuleItem::Stmt(stmt) => Some(stmt),
2201 _ => None, })
2203 .collect();
2204
2205 if let Some(opener) = output.get_mut(opener_idx) {
2207 let all_stmts: Vec<Stmt> = intermediate_stmts.into_iter().chain(closer_stmts).collect();
2208 extend_item_body(opener, all_stmts);
2209 }
2210 }
2211
2212 pub fn push_middle(item: ModuleItem, output: &mut Vec<ModuleItem>, opener_idx: usize) {
2222 let stmts = extract_function_body_statements(&item);
2224
2225 let intermediate_items: Vec<ModuleItem> = output.drain((opener_idx + 1)..).collect();
2227
2228 let intermediate_stmts: Vec<Stmt> = intermediate_items
2229 .into_iter()
2230 .filter_map(|mi| match mi {
2231 ModuleItem::Stmt(stmt) => Some(stmt),
2232 _ => None,
2233 })
2234 .collect();
2235
2236 if let Some(opener) = output.get_mut(opener_idx) {
2238 let all_stmts: Vec<Stmt> = intermediate_stmts.into_iter().chain(stmts).collect();
2239 extend_item_body(opener, all_stmts);
2240 }
2241 }
2242
2243 pub fn extract_function_body_statements(item: &ModuleItem) -> Vec<Stmt> {
2245 match item {
2246 ModuleItem::Stmt(Stmt::Decl(Decl::Fn(FnDecl { function, .. }))) => {
2248 if let Some(body) = &function.body {
2249 body.stmts.clone()
2250 } else {
2251 vec![]
2252 }
2253 }
2254 ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
2256 decl: Decl::Fn(FnDecl { function, .. }),
2257 ..
2258 })) => {
2259 if let Some(body) = &function.body {
2260 body.stmts.clone()
2261 } else {
2262 vec![]
2263 }
2264 }
2265 _ => vec![],
2266 }
2267 }
2268
2269 fn extend_item_body(item: &mut ModuleItem, stmts: Vec<Stmt>) {
2271 match item {
2272 ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
2274 decl: Decl::Fn(FnDecl { function, .. }),
2275 ..
2276 })) => {
2277 if let Some(ref mut body) = function.body {
2278 body.stmts.extend(stmts);
2279 }
2280 }
2281
2282 ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultDecl(ExportDefaultDecl {
2284 decl: DefaultDecl::Fn(FnExpr { function, .. }),
2285 ..
2286 })) => {
2287 if let Some(ref mut body) = function.body {
2288 body.stmts.extend(stmts);
2289 }
2290 }
2291
2292 ModuleItem::Stmt(Stmt::Decl(Decl::Fn(FnDecl { function, .. }))) => {
2294 if let Some(ref mut body) = function.body {
2295 body.stmts.extend(stmts);
2296 }
2297 }
2298
2299 ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
2301 decl: Decl::Class(ClassDecl { class, .. }),
2302 ..
2303 })) => {
2304 for member in class.body.iter_mut().rev() {
2306 match member {
2307 ClassMember::Method(ClassMethod { function, .. }) => {
2308 if let Some(ref mut body) = function.body {
2309 body.stmts.extend(stmts);
2310 return;
2311 }
2312 }
2313 ClassMember::Constructor(Constructor {
2314 body: Some(body), ..
2315 }) => {
2316 body.stmts.extend(stmts);
2317 return;
2318 }
2319 _ => {}
2320 }
2321 }
2322 }
2323
2324 ModuleItem::Stmt(Stmt::Decl(Decl::Class(ClassDecl { class, .. }))) => {
2326 for member in class.body.iter_mut().rev() {
2327 match member {
2328 ClassMember::Method(ClassMethod { function, .. }) => {
2329 if let Some(ref mut body) = function.body {
2330 body.stmts.extend(stmts);
2331 return;
2332 }
2333 }
2334 ClassMember::Constructor(Constructor {
2335 body: Some(body), ..
2336 }) => {
2337 body.stmts.extend(stmts);
2338 return;
2339 }
2340 _ => {}
2341 }
2342 }
2343 }
2344
2345 ModuleItem::Stmt(stmt) => {
2346 extend_stmt_body(stmt, stmts);
2347 }
2348
2349 _ => {
2350 }
2352 }
2353 }
2354
2355 fn extend_stmt_body(stmt: &mut Stmt, stmts: Vec<Stmt>) {
2356 match stmt {
2357 Stmt::Block(block) => {
2358 block.stmts.extend(stmts);
2359 }
2360 Stmt::If(if_stmt) => {
2361 if let Some(alt) = if_stmt.alt.as_deref_mut() {
2362 extend_stmt_body(alt, stmts);
2363 } else {
2364 extend_stmt_body(if_stmt.cons.as_mut(), stmts);
2365 }
2366 }
2367 Stmt::For(for_stmt) => {
2368 extend_stmt_body(for_stmt.body.as_mut(), stmts);
2369 }
2370 Stmt::ForIn(for_in_stmt) => {
2371 extend_stmt_body(for_in_stmt.body.as_mut(), stmts);
2372 }
2373 Stmt::ForOf(for_of_stmt) => {
2374 extend_stmt_body(for_of_stmt.body.as_mut(), stmts);
2375 }
2376 Stmt::While(while_stmt) => {
2377 extend_stmt_body(while_stmt.body.as_mut(), stmts);
2378 }
2379 Stmt::DoWhile(do_while_stmt) => {
2380 extend_stmt_body(do_while_stmt.body.as_mut(), stmts);
2381 }
2382 Stmt::Labeled(labeled_stmt) => {
2383 extend_stmt_body(labeled_stmt.body.as_mut(), stmts);
2384 }
2385 Stmt::With(with_stmt) => {
2386 extend_stmt_body(with_stmt.body.as_mut(), stmts);
2387 }
2388 Stmt::Try(try_stmt) => {
2389 if let Some(finalizer) = &mut try_stmt.finalizer {
2390 finalizer.stmts.extend(stmts);
2391 } else if let Some(handler) = &mut try_stmt.handler {
2392 handler.body.stmts.extend(stmts);
2393 } else {
2394 try_stmt.block.stmts.extend(stmts);
2395 }
2396 }
2397 _ => {}
2398 }
2399 }
2400}
2401
2402#[cfg(feature = "swc")]
2404pub fn stmt_to_string(stmt: &swc_core::ecma::ast::Stmt) -> String {
2405 use swc_core::common::sync::Lrc;
2406 use swc_core::ecma::ast::{Module, ModuleItem};
2407 use swc_core::ecma::codegen::{Config, Emitter, text_writer::JsWriter};
2408
2409 let module = Module {
2410 span: swc_core::common::DUMMY_SP,
2411 body: vec![ModuleItem::Stmt(stmt.clone())],
2412 shebang: None,
2413 };
2414
2415 let cm = Lrc::new(swc_core::common::SourceMap::default());
2416 let mut buf = Vec::new();
2417 {
2418 let mut emitter = Emitter {
2419 cfg: Config::default(),
2420 cm: cm.clone(),
2421 comments: None,
2422 wr: JsWriter::new(cm.clone(), "\n", &mut buf, None),
2423 };
2424 let _ = emitter.emit_module(&module);
2425 }
2426 String::from_utf8(buf)
2427 .unwrap_or_default()
2428 .trim()
2429 .to_string()
2430}
2431
2432#[cfg(feature = "swc")]
2436pub fn parse_ts_to_module_items(source: &str) -> Vec<swc_core::ecma::ast::ModuleItem> {
2437 use swc_core::common::{FileName, SourceMap, sync::Lrc};
2438 use swc_core::ecma::parser::{Parser, StringInput, Syntax, TsSyntax, lexer::Lexer};
2439
2440 let cm: Lrc<SourceMap> = Lrc::new(SourceMap::default());
2441 let fm = cm.new_source_file(
2442 FileName::Custom("template.ts".into()).into(),
2443 source.to_string(),
2444 );
2445 let syntax = Syntax::Typescript(TsSyntax {
2446 tsx: true,
2447 decorators: true,
2448 ..Default::default()
2449 });
2450 let lexer = Lexer::new(
2451 syntax,
2452 swc_core::ecma::ast::EsVersion::latest(),
2453 StringInput::from(&*fm),
2454 None,
2455 );
2456 let mut parser = Parser::new_from(lexer);
2457 match parser.parse_module() {
2458 Ok(module) => module.body,
2459 Err(_) => vec![],
2460 }
2461}
2462
2463#[cfg(feature = "swc")]
2481pub fn extend_module_item_body(
2482 item: &mut swc_core::ecma::ast::ModuleItem,
2483 stmts: Vec<swc_core::ecma::ast::Stmt>,
2484) {
2485 use swc_core::ecma::ast::*;
2486
2487 match item {
2488 ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
2490 decl: Decl::Fn(FnDecl { function, .. }),
2491 ..
2492 })) => {
2493 if let Some(ref mut body) = function.body {
2494 body.stmts.extend(stmts);
2495 }
2496 }
2497
2498 ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultDecl(ExportDefaultDecl {
2500 decl: DefaultDecl::Fn(FnExpr { function, .. }),
2501 ..
2502 })) => {
2503 if let Some(ref mut body) = function.body {
2504 body.stmts.extend(stmts);
2505 }
2506 }
2507
2508 ModuleItem::Stmt(Stmt::Decl(Decl::Fn(FnDecl { function, .. }))) => {
2510 if let Some(ref mut body) = function.body {
2511 body.stmts.extend(stmts);
2512 }
2513 }
2514
2515 ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
2517 decl: Decl::Class(ClassDecl { class, .. }),
2518 ..
2519 })) => {
2520 for member in class.body.iter_mut().rev() {
2522 if let ClassMember::Method(ClassMethod { function, .. }) = member
2523 && let Some(ref mut body) = function.body
2524 {
2525 body.stmts.extend(stmts);
2526 return;
2527 }
2528 }
2529 }
2530
2531 ModuleItem::Stmt(Stmt::Decl(Decl::Class(ClassDecl { class, .. }))) => {
2533 for member in class.body.iter_mut().rev() {
2535 if let ClassMember::Method(ClassMethod { function, .. }) = member
2536 && let Some(ref mut body) = function.body
2537 {
2538 body.stmts.extend(stmts);
2539 return;
2540 }
2541 }
2542 }
2543
2544 _ => {
2546 }
2549 }
2550}