1use react_compiler_ast::File;
7use react_compiler_ast::Program;
8use react_compiler_ast::SourceType;
9use react_compiler_ast::common::BaseNode;
10use react_compiler_ast::common::RawNode;
11use react_compiler_ast::common::Position;
12use react_compiler_ast::common::SourceLocation;
13use react_compiler_ast::declarations::*;
14use react_compiler_ast::expressions::*;
15use react_compiler_ast::jsx::*;
16use react_compiler_ast::literals::*;
17use react_compiler_ast::operators::*;
18use react_compiler_ast::patterns::*;
19use react_compiler_ast::statements::*;
20use swc_common::Span;
21use swc_common::Spanned;
22use swc_ecma_ast as swc;
23
24fn wtf8_to_string(value: &swc_atoms::Wtf8Atom) -> String {
26 value.to_string_lossy().into_owned()
27}
28
29fn unknown_statement(raw: serde_json::Value) -> Statement {
32 Statement::Unknown(
33 UnknownStatement::from_raw(RawNode::from_value(&raw))
34 .expect("raw unknown node is constructed with a `type` tag"),
35 )
36}
37
38pub fn convert_module(module: &swc::Module, source_text: &str) -> File {
40 convert_module_with_source_type(module, source_text, SourceType::Module)
41}
42
43pub fn convert_module_with_source_type(
46 module: &swc::Module,
47 source_text: &str,
48 source_type: SourceType,
49) -> File {
50 let ctx = ConvertCtx::new(source_text);
51 let base = ctx.make_base_node(module.span);
52
53 let mut body: Vec<Statement> = Vec::new();
54 let mut directives: Vec<Directive> = Vec::new();
55 let mut past_directives = false;
56
57 for item in &module.body {
58 if !past_directives {
59 if let Some(dir) = try_extract_directive(item, &ctx) {
60 directives.push(dir);
61 continue;
62 }
63 past_directives = true;
64 }
65 body.push(ctx.convert_module_item(item));
66 }
67
68 let comments = extract_comments_from_source(source_text);
70
71 File {
72 base: ctx.make_base_node(module.span),
73 program: Program {
74 base,
75 body,
76 directives,
77 source_type,
78 interpreter: None,
79 source_file: None,
80 },
81 comments,
82 errors: vec![],
83 }
84}
85
86fn extract_comments_from_source(source: &str) -> Vec<react_compiler_ast::common::Comment> {
89 use react_compiler_ast::common::Comment;
90 use react_compiler_ast::common::CommentData;
91 let mut comments = Vec::new();
92 let bytes = source.as_bytes();
93 let len = bytes.len();
94 let mut i = 0;
95 let mut line_offsets = vec![0u32];
96 for (i, ch) in source.char_indices() {
97 if ch == '\n' {
98 line_offsets.push((i + 1) as u32);
99 }
100 }
101 let position = |offset: u32| {
102 let line_idx = match line_offsets.binary_search(&offset) {
103 Ok(idx) => idx,
104 Err(idx) => idx.saturating_sub(1),
105 };
106 let line_start = line_offsets[line_idx];
107 Position {
108 line: (line_idx as u32) + 1,
109 column: offset - line_start,
110 index: Some(offset),
111 }
112 };
113 let source_location = |start: u32, end: u32| SourceLocation {
114 start: position(start),
115 end: position(end),
116 filename: None,
117 identifier_name: None,
118 };
119
120 while i < len {
121 if bytes[i] == b'/' && i + 1 < len {
122 if bytes[i + 1] == b'/' {
123 let start = i as u32;
125 let content_start = i + 2;
126 let mut end = content_start;
127 while end < len && bytes[end] != b'\n' {
128 end += 1;
129 }
130 let value = String::from_utf8_lossy(&bytes[content_start..end]).to_string();
131 let end_u32 = end as u32;
132 comments.push(Comment::CommentLine(CommentData {
133 value: value.trim().to_string(),
134 start: Some(start),
135 end: Some(end_u32),
136 loc: Some(source_location(start, end_u32)),
137 }));
138 i = end;
139 continue;
140 } else if bytes[i + 1] == b'*' {
141 let start = i as u32;
143 let content_start = i + 2;
144 let mut end = content_start;
145 while end + 1 < len {
146 if bytes[end] == b'*' && bytes[end + 1] == b'/' {
147 break;
148 }
149 end += 1;
150 }
151 let value = String::from_utf8_lossy(&bytes[content_start..end]).to_string();
152 let comment_end = if end + 1 < len { end + 2 } else { end };
153 let comment_end_u32 = comment_end as u32;
154 comments.push(Comment::CommentBlock(CommentData {
155 value: value.trim().to_string(),
156 start: Some(start),
157 end: Some(comment_end_u32),
158 loc: Some(source_location(start, comment_end_u32)),
159 }));
160 i = comment_end;
161 continue;
162 }
163 }
164 if bytes[i] == b'"' || bytes[i] == b'\'' || bytes[i] == b'`' {
166 let quote = bytes[i];
167 i += 1;
168 while i < len {
169 if bytes[i] == b'\\' {
170 i += 2; continue;
172 }
173 if bytes[i] == quote {
174 break;
175 }
176 i += 1;
177 }
178 }
179 i += 1;
180 }
181
182 comments
183}
184
185fn try_extract_directive(item: &swc::ModuleItem, ctx: &ConvertCtx) -> Option<Directive> {
186 if let swc::ModuleItem::Stmt(swc::Stmt::Expr(expr_stmt)) = item {
187 if let swc::Expr::Lit(swc::Lit::Str(s)) = &*expr_stmt.expr {
188 return Some(Directive {
189 base: ctx.make_base_node(expr_stmt.span),
190 value: DirectiveLiteral {
191 base: ctx.make_base_node(s.span),
192 value: wtf8_to_string(&s.value),
193 },
194 });
195 }
196 }
197 None
198}
199
200struct ConvertCtx<'a> {
201 #[allow(dead_code)]
202 source_text: &'a str,
203 line_offsets: Vec<u32>,
204 utf16_offsets: Vec<u32>,
205}
206
207impl<'a> ConvertCtx<'a> {
208 fn new(source_text: &'a str) -> Self {
209 let mut line_offsets = vec![0u32];
210 let mut utf16_offsets = vec![0u32; source_text.len() + 1];
211 let mut utf16_offset = 0u32;
212 for (i, ch) in source_text.char_indices() {
213 let next = i + ch.len_utf8();
214 utf16_offsets[i..next].fill(utf16_offset);
215 utf16_offset += ch.len_utf16() as u32;
216 if ch == '\n' {
217 line_offsets.push(next as u32);
218 }
219 }
220 utf16_offsets[source_text.len()] = utf16_offset;
221 Self {
222 source_text,
223 line_offsets,
224 utf16_offsets,
225 }
226 }
227
228 fn make_base_node(&self, span: Span) -> BaseNode {
229 BaseNode {
230 node_type: None,
231 start: Some(span.lo.0),
232 end: Some(span.hi.0),
233 loc: Some(self.source_location(span)),
234 range: None,
235 extra: None,
236 node_id: Some(span.lo.0),
237 leading_comments: None,
238 inner_comments: None,
239 trailing_comments: None,
240 }
241 }
242
243 fn position(&self, offset: u32) -> Position {
246 let zero_based = offset.saturating_sub(1);
247 let line_idx = match self.line_offsets.binary_search(&zero_based) {
248 Ok(idx) => idx,
249 Err(idx) => idx.saturating_sub(1),
250 };
251 let line_start = self.line_offsets[line_idx];
252 let byte_idx = (zero_based as usize).min(self.utf16_offsets.len() - 1);
254 let utf16_offset = self.utf16_offsets[byte_idx];
255 let line_start_utf16 = self.utf16_offsets[line_start as usize];
256 Position {
257 line: (line_idx as u32) + 1,
258 column: utf16_offset - line_start_utf16,
259 index: Some(utf16_offset),
260 }
261 }
262
263 fn source_location(&self, span: Span) -> SourceLocation {
264 SourceLocation {
265 start: self.position(span.lo.0),
266 end: self.position(span.hi.0),
267 filename: None,
268 identifier_name: None,
269 }
270 }
271
272 fn convert_module_item(&self, item: &swc::ModuleItem) -> Statement {
273 match item {
274 swc::ModuleItem::Stmt(stmt) => self.convert_statement(stmt),
275 swc::ModuleItem::ModuleDecl(decl) => self.convert_module_decl(decl),
276 }
277 }
278
279 fn convert_module_decl(&self, decl: &swc::ModuleDecl) -> Statement {
280 match decl {
281 swc::ModuleDecl::Import(d) => {
282 Statement::ImportDeclaration(self.convert_import_declaration(d))
283 }
284 swc::ModuleDecl::ExportDecl(d) => {
285 Statement::ExportNamedDeclaration(self.convert_export_decl(d))
286 }
287 swc::ModuleDecl::ExportNamed(d) => {
288 Statement::ExportNamedDeclaration(self.convert_export_named(d))
289 }
290 swc::ModuleDecl::ExportDefaultDecl(d) => {
291 Statement::ExportDefaultDeclaration(self.convert_export_default_decl(d))
292 }
293 swc::ModuleDecl::ExportDefaultExpr(d) => {
294 Statement::ExportDefaultDeclaration(self.convert_export_default_expr(d))
295 }
296 swc::ModuleDecl::ExportAll(d) => {
297 Statement::ExportAllDeclaration(self.convert_export_all(d))
298 }
299 swc::ModuleDecl::TsImportEquals(d) => self.convert_ts_import_equals(d),
305 swc::ModuleDecl::TsExportAssignment(d) => self.convert_ts_export_assignment(d),
306 swc::ModuleDecl::TsNamespaceExport(d) => self.convert_ts_namespace_export(d),
307 }
308 }
309
310 fn raw_node_json(&self, node_type: &str, span: Span) -> serde_json::Value {
316 let mut base = self.make_base_node(span);
317 base.node_type = Some(node_type.to_string());
318 serde_json::to_value(base).expect("BaseNode serializes to JSON")
319 }
320
321 fn identifier_to_json(&self, id: &swc::Ident) -> serde_json::Value {
322 serde_json::to_value(Expression::Identifier(self.convert_ident_to_identifier(id)))
323 .expect("Identifier serializes to JSON")
324 }
325
326 fn ident_name_to_json(&self, id: &swc::IdentName) -> serde_json::Value {
327 serde_json::to_value(Expression::Identifier(Identifier {
328 base: self.make_base_node(id.span),
329 name: id.sym.to_string(),
330 type_annotation: None,
331 optional: None,
332 decorators: None,
333 }))
334 .expect("Identifier serializes to JSON")
335 }
336
337 fn ts_entity_name_to_json(&self, name: &swc::TsEntityName) -> serde_json::Value {
340 match name {
341 swc::TsEntityName::Ident(id) => self.identifier_to_json(id),
342 swc::TsEntityName::TsQualifiedName(q) => {
343 let mut raw = self.raw_node_json("TSQualifiedName", q.span);
344 raw["left"] = self.ts_entity_name_to_json(&q.left);
345 raw["right"] = self.ident_name_to_json(&q.right);
346 raw
347 }
348 }
349 }
350
351 fn convert_ts_import_equals(&self, d: &swc::TsImportEqualsDecl) -> Statement {
354 let mut raw = self.raw_node_json("TSImportEqualsDeclaration", d.span);
355 raw["importKind"] = serde_json::json!(if d.is_type_only { "type" } else { "value" });
356 raw["isExport"] = serde_json::json!(d.is_export);
357 raw["id"] = self.identifier_to_json(&d.id);
358 raw["moduleReference"] = match &d.module_ref {
359 swc::TsModuleRef::TsExternalModuleRef(r) => {
360 let mut module_ref = self.raw_node_json("TSExternalModuleReference", r.span);
361 module_ref["expression"] =
362 serde_json::to_value(Expression::StringLiteral(StringLiteral {
363 base: self.make_base_node(r.expr.span),
364 value: wtf8_to_string(&r.expr.value),
365 }))
366 .expect("StringLiteral serializes to JSON");
367 module_ref
368 }
369 swc::TsModuleRef::TsEntityName(name) => self.ts_entity_name_to_json(name),
370 };
371 unknown_statement(raw)
372 }
373
374 fn convert_ts_export_assignment(&self, d: &swc::TsExportAssignment) -> Statement {
378 let mut raw = self.raw_node_json("TSExportAssignment", d.span);
379 raw["expression"] = serde_json::to_value(self.convert_expression(&d.expr))
380 .expect("Expression serializes to JSON");
381 unknown_statement(raw)
382 }
383
384 fn convert_ts_namespace_export(&self, d: &swc::TsNamespaceExportDecl) -> Statement {
386 let mut raw = self.raw_node_json("TSNamespaceExportDeclaration", d.span);
387 raw["id"] = self.identifier_to_json(&d.id);
388 unknown_statement(raw)
389 }
390
391 fn convert_statement(&self, stmt: &swc::Stmt) -> Statement {
394 match stmt {
395 swc::Stmt::Block(s) => Statement::BlockStatement(self.convert_block_statement(s)),
396 swc::Stmt::Break(s) => Statement::BreakStatement(BreakStatement {
397 base: self.make_base_node(s.span),
398 label: s
399 .label
400 .as_ref()
401 .map(|l| self.convert_ident_to_identifier(l)),
402 }),
403 swc::Stmt::Continue(s) => Statement::ContinueStatement(ContinueStatement {
404 base: self.make_base_node(s.span),
405 label: s
406 .label
407 .as_ref()
408 .map(|l| self.convert_ident_to_identifier(l)),
409 }),
410 swc::Stmt::Debugger(s) => Statement::DebuggerStatement(DebuggerStatement {
411 base: self.make_base_node(s.span),
412 }),
413 swc::Stmt::DoWhile(s) => Statement::DoWhileStatement(DoWhileStatement {
414 base: self.make_base_node(s.span),
415 test: Box::new(self.convert_expression(&s.test)),
416 body: Box::new(self.convert_statement(&s.body)),
417 }),
418 swc::Stmt::Empty(s) => Statement::EmptyStatement(EmptyStatement {
419 base: self.make_base_node(s.span),
420 }),
421 swc::Stmt::Expr(s) => Statement::ExpressionStatement(ExpressionStatement {
422 base: self.make_base_node(s.span),
423 expression: Box::new(self.convert_expression(&s.expr)),
424 }),
425 swc::Stmt::ForIn(s) => Statement::ForInStatement(ForInStatement {
426 base: self.make_base_node(s.span),
427 left: Box::new(self.convert_for_head(&s.left)),
428 right: Box::new(self.convert_expression(&s.right)),
429 body: Box::new(self.convert_statement(&s.body)),
430 }),
431 swc::Stmt::ForOf(s) => Statement::ForOfStatement(ForOfStatement {
432 base: self.make_base_node(s.span),
433 left: Box::new(self.convert_for_head(&s.left)),
434 right: Box::new(self.convert_expression(&s.right)),
435 body: Box::new(self.convert_statement(&s.body)),
436 is_await: s.is_await,
437 }),
438 swc::Stmt::For(s) => Statement::ForStatement(ForStatement {
439 base: self.make_base_node(s.span),
440 init: s
441 .init
442 .as_ref()
443 .map(|i| Box::new(self.convert_var_decl_or_expr_to_for_init(i))),
444 test: s
445 .test
446 .as_ref()
447 .map(|t| Box::new(self.convert_expression(t))),
448 update: s
449 .update
450 .as_ref()
451 .map(|u| Box::new(self.convert_expression(u))),
452 body: Box::new(self.convert_statement(&s.body)),
453 }),
454 swc::Stmt::If(s) => Statement::IfStatement(IfStatement {
455 base: self.make_base_node(s.span),
456 test: Box::new(self.convert_expression(&s.test)),
457 consequent: Box::new(self.convert_statement(&s.cons)),
458 alternate: s.alt.as_ref().map(|a| Box::new(self.convert_statement(a))),
459 }),
460 swc::Stmt::Labeled(s) => Statement::LabeledStatement(LabeledStatement {
461 base: self.make_base_node(s.span),
462 label: self.convert_ident_to_identifier(&s.label),
463 body: Box::new(self.convert_statement(&s.body)),
464 }),
465 swc::Stmt::Return(s) => Statement::ReturnStatement(ReturnStatement {
466 base: self.make_base_node(s.span),
467 argument: s.arg.as_ref().map(|a| Box::new(self.convert_expression(a))),
468 }),
469 swc::Stmt::Switch(s) => Statement::SwitchStatement(SwitchStatement {
470 base: self.make_base_node(s.span),
471 discriminant: Box::new(self.convert_expression(&s.discriminant)),
472 cases: s
473 .cases
474 .iter()
475 .map(|c| SwitchCase {
476 base: self.make_base_node(c.span),
477 test: c
478 .test
479 .as_ref()
480 .map(|t| Box::new(self.convert_expression(t))),
481 consequent: c.cons.iter().map(|s| self.convert_statement(s)).collect(),
482 })
483 .collect(),
484 }),
485 swc::Stmt::Throw(s) => Statement::ThrowStatement(ThrowStatement {
486 base: self.make_base_node(s.span),
487 argument: Box::new(self.convert_expression(&s.arg)),
488 }),
489 swc::Stmt::Try(s) => Statement::TryStatement(TryStatement {
490 base: self.make_base_node(s.span),
491 block: self.convert_block_statement(&s.block),
492 handler: s.handler.as_ref().map(|h| self.convert_catch_clause(h)),
493 finalizer: s
494 .finalizer
495 .as_ref()
496 .map(|f| self.convert_block_statement(f)),
497 }),
498 swc::Stmt::While(s) => Statement::WhileStatement(WhileStatement {
499 base: self.make_base_node(s.span),
500 test: Box::new(self.convert_expression(&s.test)),
501 body: Box::new(self.convert_statement(&s.body)),
502 }),
503 swc::Stmt::With(s) => Statement::WithStatement(WithStatement {
504 base: self.make_base_node(s.span),
505 object: Box::new(self.convert_expression(&s.obj)),
506 body: Box::new(self.convert_statement(&s.body)),
507 }),
508 swc::Stmt::Decl(d) => self.convert_decl_to_statement(d),
509 }
510 }
511
512 fn convert_decl_to_statement(&self, decl: &swc::Decl) -> Statement {
513 match decl {
514 swc::Decl::Var(v) => {
515 Statement::VariableDeclaration(self.convert_variable_declaration(v))
516 }
517 swc::Decl::Fn(f) => Statement::FunctionDeclaration(self.convert_fn_decl(f)),
518 swc::Decl::Class(c) => Statement::ClassDeclaration(self.convert_class_decl(c)),
519 swc::Decl::TsTypeAlias(d) => {
520 Statement::TSTypeAliasDeclaration(self.convert_ts_type_alias(d))
521 }
522 swc::Decl::TsInterface(d) => {
523 Statement::TSInterfaceDeclaration(self.convert_ts_interface(d))
524 }
525 swc::Decl::TsEnum(d) => Statement::TSEnumDeclaration(self.convert_ts_enum(d)),
526 swc::Decl::TsModule(d) => Statement::TSModuleDeclaration(self.convert_ts_module(d)),
527 swc::Decl::Using(u) => Statement::VariableDeclaration(self.convert_using_decl(u)),
528 }
529 }
530
531 fn convert_block_statement(&self, block: &swc::BlockStmt) -> BlockStatement {
532 let mut body: Vec<Statement> = Vec::new();
533 let mut directives: Vec<Directive> = Vec::new();
534 let mut past_directives = false;
535
536 for stmt in &block.stmts {
537 if !past_directives {
538 if let Some(dir) = self.try_extract_block_directive(stmt) {
539 directives.push(dir);
540 continue;
541 }
542 past_directives = true;
543 }
544 body.push(self.convert_statement(stmt));
545 }
546
547 BlockStatement {
548 base: self.make_base_node(block.span),
549 body,
550 directives,
551 }
552 }
553
554 fn try_extract_block_directive(&self, stmt: &swc::Stmt) -> Option<Directive> {
557 if let swc::Stmt::Expr(expr_stmt) = stmt {
558 if let swc::Expr::Lit(swc::Lit::Str(s)) = &*expr_stmt.expr {
559 return Some(Directive {
560 base: self.make_base_node(expr_stmt.span),
561 value: DirectiveLiteral {
562 base: self.make_base_node(s.span),
563 value: wtf8_to_string(&s.value),
564 },
565 });
566 }
567 }
568 None
569 }
570
571 fn convert_catch_clause(&self, clause: &swc::CatchClause) -> CatchClause {
572 CatchClause {
573 base: self.make_base_node(clause.span),
574 param: clause.param.as_ref().map(|p| self.convert_pat(p)),
575 body: self.convert_block_statement(&clause.body),
576 }
577 }
578
579 fn convert_var_decl_or_expr_to_for_init(&self, init: &swc::VarDeclOrExpr) -> ForInit {
580 match init {
581 swc::VarDeclOrExpr::VarDecl(v) => {
582 ForInit::VariableDeclaration(self.convert_variable_declaration(v))
583 }
584 swc::VarDeclOrExpr::Expr(e) => {
585 ForInit::Expression(Box::new(self.convert_expression(e)))
586 }
587 }
588 }
589
590 fn convert_for_head(&self, head: &swc::ForHead) -> ForInOfLeft {
591 match head {
592 swc::ForHead::VarDecl(v) => {
593 ForInOfLeft::VariableDeclaration(self.convert_variable_declaration(v))
594 }
595 swc::ForHead::Pat(p) => ForInOfLeft::Pattern(Box::new(self.convert_pat(p))),
596 swc::ForHead::UsingDecl(u) => {
597 ForInOfLeft::VariableDeclaration(self.convert_using_decl(u))
598 }
599 }
600 }
601
602 fn convert_variable_declaration(&self, decl: &swc::VarDecl) -> VariableDeclaration {
603 VariableDeclaration {
604 base: self.make_base_node(decl.span),
605 declarations: decl
606 .decls
607 .iter()
608 .map(|d| self.convert_variable_declarator(d))
609 .collect(),
610 kind: match decl.kind {
611 swc::VarDeclKind::Var => VariableDeclarationKind::Var,
612 swc::VarDeclKind::Let => VariableDeclarationKind::Let,
613 swc::VarDeclKind::Const => VariableDeclarationKind::Const,
614 },
615 declare: if decl.declare { Some(true) } else { None },
616 }
617 }
618
619 fn convert_using_decl(&self, decl: &swc::UsingDecl) -> VariableDeclaration {
620 VariableDeclaration {
621 base: self.make_base_node(decl.span),
622 declarations: decl
623 .decls
624 .iter()
625 .map(|d| self.convert_variable_declarator(d))
626 .collect(),
627 kind: VariableDeclarationKind::Using,
628 declare: None,
629 }
630 }
631
632 fn convert_variable_declarator(&self, d: &swc::VarDeclarator) -> VariableDeclarator {
633 VariableDeclarator {
634 base: self.make_base_node(d.span),
635 id: self.convert_pat(&d.name),
636 init: d
637 .init
638 .as_ref()
639 .map(|e| Box::new(self.convert_expression(e))),
640 definite: if d.definite { Some(true) } else { None },
641 }
642 }
643
644 fn convert_expression(&self, expr: &swc::Expr) -> Expression {
647 match expr {
648 swc::Expr::Lit(lit) => self.convert_lit(lit),
649 swc::Expr::Ident(id) => Expression::Identifier(self.convert_ident_to_identifier(id)),
650 swc::Expr::This(t) => Expression::ThisExpression(ThisExpression {
651 base: self.make_base_node(t.span),
652 }),
653 swc::Expr::Array(arr) => {
654 Expression::ArrayExpression(self.convert_array_expression(arr))
655 }
656 swc::Expr::Object(obj) => {
657 Expression::ObjectExpression(self.convert_object_expression(obj))
658 }
659 swc::Expr::Fn(f) => Expression::FunctionExpression(self.convert_fn_expr(f)),
660 swc::Expr::Unary(un) => Expression::UnaryExpression(UnaryExpression {
661 base: self.make_base_node(un.span),
662 operator: self.convert_unary_operator(un.op),
663 prefix: true,
664 argument: Box::new(self.convert_expression(&un.arg)),
665 }),
666 swc::Expr::Update(up) => Expression::UpdateExpression(UpdateExpression {
667 base: self.make_base_node(up.span),
668 operator: self.convert_update_operator(up.op),
669 argument: Box::new(self.convert_expression(&up.arg)),
670 prefix: up.prefix,
671 }),
672 swc::Expr::Bin(bin) => {
673 if let Some(log_op) = self.try_convert_logical_operator(bin.op) {
674 Expression::LogicalExpression(LogicalExpression {
675 base: self.make_base_node(bin.span),
676 operator: log_op,
677 left: Box::new(self.convert_expression(&bin.left)),
678 right: Box::new(self.convert_expression(&bin.right)),
679 })
680 } else {
681 Expression::BinaryExpression(BinaryExpression {
682 base: self.make_base_node(bin.span),
683 operator: self.convert_binary_operator(bin.op),
684 left: Box::new(self.convert_expression(&bin.left)),
685 right: Box::new(self.convert_expression(&bin.right)),
686 })
687 }
688 }
689 swc::Expr::Assign(a) => {
690 Expression::AssignmentExpression(self.convert_assignment_expression(a))
691 }
692 swc::Expr::Member(m) => Expression::MemberExpression(self.convert_member_expression(m)),
693 swc::Expr::SuperProp(sp) => {
694 let (property, computed) = self.convert_super_prop(&sp.prop);
695 Expression::MemberExpression(MemberExpression {
696 base: self.make_base_node(sp.span),
697 object: Box::new(Expression::Super(Super {
698 base: self.make_base_node(sp.obj.span),
699 })),
700 property: Box::new(property),
701 computed,
702 })
703 }
704 swc::Expr::Cond(c) => Expression::ConditionalExpression(ConditionalExpression {
705 base: self.make_base_node(c.span),
706 test: Box::new(self.convert_expression(&c.test)),
707 consequent: Box::new(self.convert_expression(&c.cons)),
708 alternate: Box::new(self.convert_expression(&c.alt)),
709 }),
710 swc::Expr::Call(call) => Expression::CallExpression(self.convert_call_expression(call)),
711 swc::Expr::New(n) => Expression::NewExpression(NewExpression {
712 base: self.make_base_node(n.span),
713 callee: Box::new(self.convert_expression(&n.callee)),
714 arguments: n.args.as_ref().map_or_else(Vec::new, |args| {
715 args.iter()
716 .map(|a| self.convert_expr_or_spread(a))
717 .collect()
718 }),
719 type_parameters: None,
720 type_arguments: None,
721 }),
722 swc::Expr::Seq(seq) => Expression::SequenceExpression(SequenceExpression {
723 base: self.make_base_node(seq.span),
724 expressions: seq
725 .exprs
726 .iter()
727 .map(|e| self.convert_expression(e))
728 .collect(),
729 }),
730 swc::Expr::Arrow(arrow) => {
731 Expression::ArrowFunctionExpression(self.convert_arrow_function(arrow))
732 }
733 swc::Expr::Class(class) => {
734 Expression::ClassExpression(self.convert_class_expression(class))
735 }
736 swc::Expr::Yield(y) => Expression::YieldExpression(YieldExpression {
737 base: self.make_base_node(y.span),
738 argument: y.arg.as_ref().map(|a| Box::new(self.convert_expression(a))),
739 delegate: y.delegate,
740 }),
741 swc::Expr::Await(a) => Expression::AwaitExpression(AwaitExpression {
742 base: self.make_base_node(a.span),
743 argument: Box::new(self.convert_expression(&a.arg)),
744 }),
745 swc::Expr::MetaProp(mp) => {
746 let (meta_name, prop_name) = match mp.kind {
747 swc::MetaPropKind::NewTarget => ("new", "target"),
748 swc::MetaPropKind::ImportMeta => ("import", "meta"),
749 };
750 Expression::MetaProperty(MetaProperty {
751 base: self.make_base_node(mp.span),
752 meta: Identifier {
753 base: self.make_base_node(mp.span),
754 name: meta_name.to_string(),
755 type_annotation: None,
756 optional: None,
757 decorators: None,
758 },
759 property: Identifier {
760 base: self.make_base_node(mp.span),
761 name: prop_name.to_string(),
762 type_annotation: None,
763 optional: None,
764 decorators: None,
765 },
766 })
767 }
768 swc::Expr::Tpl(tpl) => Expression::TemplateLiteral(self.convert_template_literal(tpl)),
769 swc::Expr::TaggedTpl(tag) => {
770 Expression::TaggedTemplateExpression(TaggedTemplateExpression {
771 base: self.make_base_node(tag.span),
772 tag: Box::new(self.convert_expression(&tag.tag)),
773 quasi: self.convert_template_literal(&tag.tpl),
774 type_parameters: None,
775 })
776 }
777 swc::Expr::Paren(p) => Expression::ParenthesizedExpression(ParenthesizedExpression {
778 base: self.make_base_node(p.span),
779 expression: Box::new(self.convert_expression(&p.expr)),
780 }),
781 swc::Expr::OptChain(chain) => self.convert_opt_chain_expression(chain),
782 swc::Expr::PrivateName(p) => Expression::PrivateName(PrivateName {
783 base: self.make_base_node(p.span),
784 id: Identifier {
785 base: self.make_base_node(p.span),
786 name: p.name.to_string(),
787 type_annotation: None,
788 optional: None,
789 decorators: None,
790 },
791 }),
792 swc::Expr::JSXElement(el) => {
793 Expression::JSXElement(Box::new(self.convert_jsx_element(el)))
794 }
795 swc::Expr::JSXFragment(frag) => {
796 Expression::JSXFragment(self.convert_jsx_fragment(frag))
797 }
798 swc::Expr::JSXEmpty(e) => Expression::Identifier(Identifier {
799 base: self.make_base_node(e.span),
800 name: "undefined".to_string(),
801 type_annotation: None,
802 optional: None,
803 decorators: None,
804 }),
805 swc::Expr::JSXMember(m) => Expression::Identifier(Identifier {
806 base: self.make_base_node(m.prop.span),
807 name: m.prop.sym.to_string(),
808 type_annotation: None,
809 optional: None,
810 decorators: None,
811 }),
812 swc::Expr::JSXNamespacedName(n) => Expression::Identifier(Identifier {
813 base: self.make_base_node(n.name.span),
814 name: format!("{}:{}", n.ns.sym, n.name.sym),
815 type_annotation: None,
816 optional: None,
817 decorators: None,
818 }),
819 swc::Expr::TsAs(e) => Expression::TSAsExpression(TSAsExpression {
820 base: self.make_base_node(e.span),
821 expression: Box::new(self.convert_expression(&e.expr)),
822 type_annotation: RawNode::from_value(
823 &self.convert_ts_type_to_json(&e.type_ann)
824 .unwrap_or(serde_json::Value::Null),
825 ),
826 }),
827 swc::Expr::TsSatisfies(e) => Expression::TSSatisfiesExpression(TSSatisfiesExpression {
828 base: self.make_base_node(e.span),
829 expression: Box::new(self.convert_expression(&e.expr)),
830 type_annotation: RawNode::from_value(
831 &self.convert_ts_type_to_json(&e.type_ann)
832 .unwrap_or(serde_json::Value::Null),
833 ),
834 }),
835 swc::Expr::TsTypeAssertion(e) => Expression::TSTypeAssertion(TSTypeAssertion {
836 base: self.make_base_node(e.span),
837 expression: Box::new(self.convert_expression(&e.expr)),
838 type_annotation: RawNode::from_value(
839 &self.convert_ts_type_to_json(&e.type_ann)
840 .unwrap_or(serde_json::Value::Null),
841 ),
842 }),
843 swc::Expr::TsNonNull(e) => Expression::TSNonNullExpression(TSNonNullExpression {
844 base: self.make_base_node(e.span),
845 expression: Box::new(self.convert_expression(&e.expr)),
846 }),
847 swc::Expr::TsInstantiation(e) => {
848 Expression::TSInstantiationExpression(TSInstantiationExpression {
849 base: self.make_base_node(e.span),
850 expression: Box::new(self.convert_expression(&e.expr)),
851 type_parameters: RawNode::null(),
852 })
853 }
854 swc::Expr::TsConstAssertion(e) => {
855 let type_ann = serde_json::json!({
858 "type": "TSTypeReference",
859 "typeName": {
860 "type": "Identifier",
861 "name": "const"
862 }
863 });
864 Expression::TSAsExpression(TSAsExpression {
865 base: self.make_base_node(e.span),
866 expression: Box::new(self.convert_expression(&e.expr)),
867 type_annotation: RawNode::from_value(&type_ann),
868 })
869 }
870 swc::Expr::Invalid(i) => Expression::Identifier(Identifier {
871 base: self.make_base_node(i.span),
872 name: "__invalid__".to_string(),
873 type_annotation: None,
874 optional: None,
875 decorators: None,
876 }),
877 }
878 }
879
880 fn convert_lit(&self, lit: &swc::Lit) -> Expression {
881 match lit {
882 swc::Lit::Str(s) => Expression::StringLiteral(StringLiteral {
883 base: self.make_base_node(s.span),
884 value: wtf8_to_string(&s.value),
885 }),
886 swc::Lit::Bool(b) => Expression::BooleanLiteral(BooleanLiteral {
887 base: self.make_base_node(b.span),
888 value: b.value,
889 }),
890 swc::Lit::Null(n) => Expression::NullLiteral(NullLiteral {
891 base: self.make_base_node(n.span),
892 }),
893 swc::Lit::Num(n) => Expression::NumericLiteral(NumericLiteral {
894 base: self.make_base_node(n.span),
895 value: n.value,
896 extra: None,
897 }),
898 swc::Lit::BigInt(b) => Expression::BigIntLiteral(BigIntLiteral {
899 base: self.make_base_node(b.span),
900 value: b.value.to_string(),
901 }),
902 swc::Lit::Regex(r) => Expression::RegExpLiteral(RegExpLiteral {
903 base: self.make_base_node(r.span),
904 pattern: r.exp.to_string(),
905 flags: r.flags.to_string(),
906 }),
907 swc::Lit::JSXText(t) => Expression::StringLiteral(StringLiteral {
908 base: self.make_base_node(t.span),
909 value: t.value.to_string(),
910 }),
911 }
912 }
913
914 fn convert_opt_chain_expression(&self, chain: &swc::OptChainExpr) -> Expression {
917 match &*chain.base {
918 swc::OptChainBase::Member(m) => {
919 let (property, computed) = self.convert_member_prop(&m.prop);
920 Expression::OptionalMemberExpression(OptionalMemberExpression {
921 base: self.make_base_node(chain.span),
922 object: Box::new(self.convert_opt_chain_callee(&m.obj)),
923 property: Box::new(property),
924 computed,
925 optional: chain.optional,
926 })
927 }
928 swc::OptChainBase::Call(call) => {
929 Expression::OptionalCallExpression(OptionalCallExpression {
930 base: self.make_base_node(chain.span),
931 callee: Box::new(self.convert_opt_chain_callee(&call.callee)),
932 arguments: call
933 .args
934 .iter()
935 .map(|a| self.convert_expr_or_spread(a))
936 .collect(),
937 optional: chain.optional,
938 type_parameters: None,
939 type_arguments: None,
940 })
941 }
942 }
943 }
944
945 fn convert_opt_chain_callee(&self, expr: &swc::Expr) -> Expression {
946 if let swc::Expr::OptChain(chain) = expr {
947 return self.convert_opt_chain_expression(chain);
948 }
949 self.convert_expression(expr)
950 }
951
952 fn convert_member_expression(&self, m: &swc::MemberExpr) -> MemberExpression {
955 let (property, computed) = self.convert_member_prop(&m.prop);
956 MemberExpression {
957 base: self.make_base_node(m.span),
958 object: Box::new(self.convert_expression(&m.obj)),
959 property: Box::new(property),
960 computed,
961 }
962 }
963
964 fn convert_member_prop(&self, prop: &swc::MemberProp) -> (Expression, bool) {
965 match prop {
966 swc::MemberProp::Ident(id) => (
967 Expression::Identifier(Identifier {
968 base: self.make_base_node(id.span),
969 name: id.sym.to_string(),
970 type_annotation: None,
971 optional: None,
972 decorators: None,
973 }),
974 false,
975 ),
976 swc::MemberProp::Computed(c) => (self.convert_expression(&c.expr), true),
977 swc::MemberProp::PrivateName(p) => (
978 Expression::PrivateName(PrivateName {
979 base: self.make_base_node(p.span),
980 id: Identifier {
981 base: self.make_base_node(p.span),
982 name: p.name.to_string(),
983 type_annotation: None,
984 optional: None,
985 decorators: None,
986 },
987 }),
988 false,
989 ),
990 }
991 }
992
993 fn convert_super_prop(&self, prop: &swc::SuperProp) -> (Expression, bool) {
994 match prop {
995 swc::SuperProp::Ident(id) => (
996 Expression::Identifier(Identifier {
997 base: self.make_base_node(id.span),
998 name: id.sym.to_string(),
999 type_annotation: None,
1000 optional: None,
1001 decorators: None,
1002 }),
1003 false,
1004 ),
1005 swc::SuperProp::Computed(c) => (self.convert_expression(&c.expr), true),
1006 }
1007 }
1008
1009 fn convert_call_expression(&self, call: &swc::CallExpr) -> CallExpression {
1012 CallExpression {
1013 base: self.make_base_node(call.span),
1014 callee: Box::new(self.convert_callee(&call.callee)),
1015 arguments: call
1016 .args
1017 .iter()
1018 .map(|a| self.convert_expr_or_spread(a))
1019 .collect(),
1020 type_parameters: None,
1021 type_arguments: None,
1022 optional: None,
1023 }
1024 }
1025
1026 fn convert_callee(&self, callee: &swc::Callee) -> Expression {
1027 match callee {
1028 swc::Callee::Expr(e) => self.convert_expression(e),
1029 swc::Callee::Super(s) => Expression::Super(Super {
1030 base: self.make_base_node(s.span),
1031 }),
1032 swc::Callee::Import(i) => Expression::Import(Import {
1033 base: self.make_base_node(i.span),
1034 }),
1035 }
1036 }
1037
1038 fn convert_expr_or_spread(&self, arg: &swc::ExprOrSpread) -> Expression {
1039 if let Some(spread_span) = arg.spread {
1040 Expression::SpreadElement(SpreadElement {
1041 base: self.make_base_node(Span::new(spread_span.lo, arg.expr.span().hi)),
1042 argument: Box::new(self.convert_expression(&arg.expr)),
1043 })
1044 } else {
1045 self.convert_expression(&arg.expr)
1046 }
1047 }
1048
1049 fn convert_fn_decl(&self, func: &swc::FnDecl) -> FunctionDeclaration {
1052 let f = &func.function;
1053 let body = f
1054 .body
1055 .as_ref()
1056 .map(|b| self.convert_block_statement(b))
1057 .unwrap_or_else(|| BlockStatement {
1058 base: self.make_base_node(f.span),
1059 body: vec![],
1060 directives: vec![],
1061 });
1062 FunctionDeclaration {
1063 base: self.make_base_node(f.span),
1064 id: Some(self.convert_ident_to_identifier(&func.ident)),
1065 params: self.convert_params(&f.params),
1066 body,
1067 generator: f.is_generator,
1068 is_async: f.is_async,
1069 declare: if func.declare { Some(true) } else { None },
1070 return_type: f
1071 .return_type
1072 .as_ref()
1073 .map(|_| RawNode::null()),
1074 type_parameters: f
1075 .type_params
1076 .as_ref()
1077 .map(|_| RawNode::null()),
1078 predicate: None,
1079 component_declaration: false,
1080 hook_declaration: false,
1081 }
1082 }
1083
1084 fn convert_fn_expr(&self, func: &swc::FnExpr) -> FunctionExpression {
1085 let f = &func.function;
1086 let body = f
1087 .body
1088 .as_ref()
1089 .map(|b| self.convert_block_statement(b))
1090 .unwrap_or_else(|| BlockStatement {
1091 base: self.make_base_node(f.span),
1092 body: vec![],
1093 directives: vec![],
1094 });
1095 FunctionExpression {
1096 base: self.make_base_node(f.span),
1097 id: func
1098 .ident
1099 .as_ref()
1100 .map(|id| self.convert_ident_to_identifier(id)),
1101 params: self.convert_params(&f.params),
1102 body,
1103 generator: f.is_generator,
1104 is_async: f.is_async,
1105 return_type: f
1106 .return_type
1107 .as_ref()
1108 .map(|_| RawNode::null()),
1109 type_parameters: f
1110 .type_params
1111 .as_ref()
1112 .map(|_| RawNode::null()),
1113 predicate: None,
1114 }
1115 }
1116
1117 fn convert_arrow_function(&self, arrow: &swc::ArrowExpr) -> ArrowFunctionExpression {
1118 let is_expression = matches!(&*arrow.body, swc::BlockStmtOrExpr::Expr(_));
1119 let body = match &*arrow.body {
1120 swc::BlockStmtOrExpr::BlockStmt(block) => {
1121 ArrowFunctionBody::BlockStatement(self.convert_block_statement(block))
1122 }
1123 swc::BlockStmtOrExpr::Expr(expr) => {
1124 ArrowFunctionBody::Expression(Box::new(self.convert_expression(expr)))
1125 }
1126 };
1127 ArrowFunctionExpression {
1128 base: self.make_base_node(arrow.span),
1129 params: arrow.params.iter().map(|p| self.convert_pat(p)).collect(),
1130 body: Box::new(body),
1131 id: None,
1132 generator: arrow.is_generator,
1133 is_async: arrow.is_async,
1134 expression: Some(is_expression),
1135 return_type: arrow
1136 .return_type
1137 .as_ref()
1138 .map(|_| RawNode::null()),
1139 type_parameters: arrow
1140 .type_params
1141 .as_ref()
1142 .map(|_| RawNode::null()),
1143 predicate: None,
1144 }
1145 }
1146
1147 fn convert_params(&self, params: &[swc::Param]) -> Vec<PatternLike> {
1148 params.iter().map(|p| self.convert_pat(&p.pat)).collect()
1149 }
1150
1151 fn convert_pat(&self, pat: &swc::Pat) -> PatternLike {
1154 match pat {
1155 swc::Pat::Ident(id) => PatternLike::Identifier(self.convert_binding_ident(id)),
1156 swc::Pat::Array(arr) => PatternLike::ArrayPattern(self.convert_array_pattern(arr)),
1157 swc::Pat::Object(obj) => PatternLike::ObjectPattern(self.convert_object_pattern(obj)),
1158 swc::Pat::Assign(a) => PatternLike::AssignmentPattern(AssignmentPattern {
1159 base: self.make_base_node(a.span),
1160 left: Box::new(self.convert_pat(&a.left)),
1161 right: Box::new(self.convert_expression(&a.right)),
1162 type_annotation: None,
1163 decorators: None,
1164 }),
1165 swc::Pat::Rest(r) => PatternLike::RestElement(RestElement {
1166 base: self.make_base_node(r.span),
1167 argument: Box::new(self.convert_pat(&r.arg)),
1168 type_annotation: None,
1169 decorators: None,
1170 }),
1171 swc::Pat::Expr(e) => self.convert_expression_to_pattern(e),
1172 swc::Pat::Invalid(i) => PatternLike::Identifier(Identifier {
1173 base: self.make_base_node(i.span),
1174 name: "__invalid__".to_string(),
1175 type_annotation: None,
1176 optional: None,
1177 decorators: None,
1178 }),
1179 }
1180 }
1181
1182 fn convert_expression_to_pattern(&self, expr: &swc::Expr) -> PatternLike {
1183 match expr {
1184 swc::Expr::Ident(id) => PatternLike::Identifier(self.convert_ident_to_identifier(id)),
1185 swc::Expr::Member(m) => {
1186 PatternLike::MemberExpression(self.convert_member_expression(m))
1187 }
1188 _ => PatternLike::Identifier(Identifier {
1189 base: self.make_base_node(expr.span()),
1190 name: "__unknown_target__".to_string(),
1191 type_annotation: None,
1192 optional: None,
1193 decorators: None,
1194 }),
1195 }
1196 }
1197
1198 fn convert_object_pattern(&self, obj: &swc::ObjectPat) -> ObjectPattern {
1199 let properties = obj
1200 .props
1201 .iter()
1202 .map(|p| match p {
1203 swc::ObjectPatProp::KeyValue(kv) => {
1204 ObjectPatternProperty::ObjectProperty(ObjectPatternProp {
1205 base: self.make_base_node(kv.span()),
1206 key: Box::new(self.convert_prop_name(&kv.key)),
1207 value: Box::new(self.convert_pat(&kv.value)),
1208 computed: matches!(kv.key, swc::PropName::Computed(_)),
1209 shorthand: false,
1210 decorators: None,
1211 method: None,
1212 })
1213 }
1214 swc::ObjectPatProp::Assign(a) => {
1215 let id = self.convert_ident_to_identifier(&a.key.id);
1216 let (value, shorthand) = if let Some(ref init) = a.value {
1217 (
1218 Box::new(PatternLike::AssignmentPattern(AssignmentPattern {
1219 base: self.make_base_node(a.span),
1220 left: Box::new(PatternLike::Identifier(id.clone())),
1221 right: Box::new(self.convert_expression(init)),
1222 type_annotation: None,
1223 decorators: None,
1224 })),
1225 true,
1226 )
1227 } else {
1228 (Box::new(PatternLike::Identifier(id.clone())), true)
1229 };
1230 ObjectPatternProperty::ObjectProperty(ObjectPatternProp {
1231 base: self.make_base_node(a.span),
1232 key: Box::new(Expression::Identifier(id)),
1233 value,
1234 computed: false,
1235 shorthand,
1236 decorators: None,
1237 method: None,
1238 })
1239 }
1240 swc::ObjectPatProp::Rest(r) => ObjectPatternProperty::RestElement(RestElement {
1241 base: self.make_base_node(r.span),
1242 argument: Box::new(self.convert_pat(&r.arg)),
1243 type_annotation: None,
1244 decorators: None,
1245 }),
1246 })
1247 .collect();
1248 ObjectPattern {
1249 base: self.make_base_node(obj.span),
1250 properties,
1251 type_annotation: obj
1252 .type_ann
1253 .as_ref()
1254 .map(|_| RawNode::null()),
1255 decorators: None,
1256 }
1257 }
1258
1259 fn convert_array_pattern(&self, arr: &swc::ArrayPat) -> ArrayPattern {
1260 ArrayPattern {
1261 base: self.make_base_node(arr.span),
1262 elements: arr
1263 .elems
1264 .iter()
1265 .map(|e| e.as_ref().map(|p| self.convert_pat(p)))
1266 .collect(),
1267 type_annotation: arr
1268 .type_ann
1269 .as_ref()
1270 .map(|_| RawNode::null()),
1271 decorators: None,
1272 }
1273 }
1274
1275 fn convert_assign_target(&self, target: &swc::AssignTarget) -> PatternLike {
1278 match target {
1279 swc::AssignTarget::Simple(s) => self.convert_simple_assign_target(s),
1280 swc::AssignTarget::Pat(p) => self.convert_assign_target_pat(p),
1281 }
1282 }
1283
1284 fn convert_simple_assign_target(&self, target: &swc::SimpleAssignTarget) -> PatternLike {
1285 match target {
1286 swc::SimpleAssignTarget::Ident(id) => {
1287 PatternLike::Identifier(self.convert_binding_ident(id))
1288 }
1289 swc::SimpleAssignTarget::Member(m) => {
1290 PatternLike::MemberExpression(self.convert_member_expression(m))
1291 }
1292 swc::SimpleAssignTarget::SuperProp(sp) => {
1293 let (property, computed) = self.convert_super_prop(&sp.prop);
1294 PatternLike::MemberExpression(MemberExpression {
1295 base: self.make_base_node(sp.span),
1296 object: Box::new(Expression::Super(Super {
1297 base: self.make_base_node(sp.obj.span),
1298 })),
1299 property: Box::new(property),
1300 computed,
1301 })
1302 }
1303 swc::SimpleAssignTarget::Paren(p) => self.convert_expression_to_pattern(&p.expr),
1304 swc::SimpleAssignTarget::OptChain(o) => PatternLike::Identifier(Identifier {
1305 base: self.make_base_node(o.span),
1306 name: "__unknown_target__".to_string(),
1307 type_annotation: None,
1308 optional: None,
1309 decorators: None,
1310 }),
1311 swc::SimpleAssignTarget::TsAs(e) => self.convert_expression_to_pattern(&e.expr),
1312 swc::SimpleAssignTarget::TsSatisfies(e) => self.convert_expression_to_pattern(&e.expr),
1313 swc::SimpleAssignTarget::TsNonNull(e) => self.convert_expression_to_pattern(&e.expr),
1314 swc::SimpleAssignTarget::TsTypeAssertion(e) => {
1315 self.convert_expression_to_pattern(&e.expr)
1316 }
1317 swc::SimpleAssignTarget::TsInstantiation(e) => {
1318 self.convert_expression_to_pattern(&e.expr)
1319 }
1320 swc::SimpleAssignTarget::Invalid(i) => PatternLike::Identifier(Identifier {
1321 base: self.make_base_node(i.span),
1322 name: "__invalid__".to_string(),
1323 type_annotation: None,
1324 optional: None,
1325 decorators: None,
1326 }),
1327 }
1328 }
1329
1330 fn convert_assign_target_pat(&self, target: &swc::AssignTargetPat) -> PatternLike {
1331 match target {
1332 swc::AssignTargetPat::Array(a) => {
1333 PatternLike::ArrayPattern(self.convert_array_pattern(a))
1334 }
1335 swc::AssignTargetPat::Object(o) => {
1336 PatternLike::ObjectPattern(self.convert_object_pattern(o))
1337 }
1338 swc::AssignTargetPat::Invalid(i) => PatternLike::Identifier(Identifier {
1339 base: self.make_base_node(i.span),
1340 name: "__invalid__".to_string(),
1341 type_annotation: None,
1342 optional: None,
1343 decorators: None,
1344 }),
1345 }
1346 }
1347
1348 fn convert_assignment_expression(&self, assign: &swc::AssignExpr) -> AssignmentExpression {
1349 AssignmentExpression {
1350 base: self.make_base_node(assign.span),
1351 operator: self.convert_assignment_operator(assign.op),
1352 left: Box::new(self.convert_assign_target(&assign.left)),
1353 right: Box::new(self.convert_expression(&assign.right)),
1354 }
1355 }
1356
1357 fn convert_object_expression(&self, obj: &swc::ObjectLit) -> ObjectExpression {
1360 ObjectExpression {
1361 base: self.make_base_node(obj.span),
1362 properties: obj
1363 .props
1364 .iter()
1365 .map(|p| self.convert_prop_or_spread(p))
1366 .collect(),
1367 }
1368 }
1369
1370 fn convert_prop_or_spread(&self, prop: &swc::PropOrSpread) -> ObjectExpressionProperty {
1371 match prop {
1372 swc::PropOrSpread::Spread(s) => {
1373 ObjectExpressionProperty::SpreadElement(SpreadElement {
1374 base: self.make_base_node(s.span()),
1375 argument: Box::new(self.convert_expression(&s.expr)),
1376 })
1377 }
1378 swc::PropOrSpread::Prop(p) => self.convert_prop(p),
1379 }
1380 }
1381
1382 fn convert_prop(&self, prop: &swc::Prop) -> ObjectExpressionProperty {
1383 match prop {
1384 swc::Prop::Shorthand(id) => {
1385 let ident = self.convert_ident_to_identifier(id);
1386 ObjectExpressionProperty::ObjectProperty(ObjectProperty {
1387 base: self.make_base_node(id.span),
1388 key: Box::new(Expression::Identifier(ident.clone())),
1389 value: Box::new(Expression::Identifier(ident)),
1390 computed: false,
1391 shorthand: true,
1392 decorators: None,
1393 method: Some(false),
1394 })
1395 }
1396 swc::Prop::KeyValue(kv) => ObjectExpressionProperty::ObjectProperty(ObjectProperty {
1397 base: self.make_base_node(kv.span()),
1398 key: Box::new(self.convert_prop_name(&kv.key)),
1399 value: Box::new(self.convert_expression(&kv.value)),
1400 computed: matches!(kv.key, swc::PropName::Computed(_)),
1401 shorthand: false,
1402 decorators: None,
1403 method: Some(false),
1404 }),
1405 swc::Prop::Getter(g) => ObjectExpressionProperty::ObjectMethod(ObjectMethod {
1406 base: self.make_base_node(g.span),
1407 method: false,
1408 kind: ObjectMethodKind::Get,
1409 key: Box::new(self.convert_prop_name(&g.key)),
1410 params: vec![],
1411 body: g
1412 .body
1413 .as_ref()
1414 .map(|b| self.convert_block_statement(b))
1415 .unwrap_or_else(|| BlockStatement {
1416 base: self.make_base_node(g.span),
1417 body: vec![],
1418 directives: vec![],
1419 }),
1420 computed: matches!(g.key, swc::PropName::Computed(_)),
1421 id: None,
1422 generator: false,
1423 is_async: false,
1424 decorators: None,
1425 return_type: g
1426 .type_ann
1427 .as_ref()
1428 .map(|_| RawNode::null()),
1429 type_parameters: None,
1430 predicate: None,
1431 }),
1432 swc::Prop::Setter(s) => ObjectExpressionProperty::ObjectMethod(ObjectMethod {
1433 base: self.make_base_node(s.span),
1434 method: false,
1435 kind: ObjectMethodKind::Set,
1436 key: Box::new(self.convert_prop_name(&s.key)),
1437 params: vec![self.convert_pat(&s.param)],
1438 body: s
1439 .body
1440 .as_ref()
1441 .map(|b| self.convert_block_statement(b))
1442 .unwrap_or_else(|| BlockStatement {
1443 base: self.make_base_node(s.span),
1444 body: vec![],
1445 directives: vec![],
1446 }),
1447 computed: matches!(s.key, swc::PropName::Computed(_)),
1448 id: None,
1449 generator: false,
1450 is_async: false,
1451 decorators: None,
1452 return_type: None,
1453 type_parameters: None,
1454 predicate: None,
1455 }),
1456 swc::Prop::Method(m) => ObjectExpressionProperty::ObjectMethod(ObjectMethod {
1457 base: self.make_base_node(m.span()),
1458 method: true,
1459 kind: ObjectMethodKind::Method,
1460 key: Box::new(self.convert_prop_name(&m.key)),
1461 params: self.convert_params(&m.function.params),
1462 body: m
1463 .function
1464 .body
1465 .as_ref()
1466 .map(|b| self.convert_block_statement(b))
1467 .unwrap_or_else(|| BlockStatement {
1468 base: self.make_base_node(m.function.span),
1469 body: vec![],
1470 directives: vec![],
1471 }),
1472 computed: matches!(m.key, swc::PropName::Computed(_)),
1473 id: None,
1474 generator: m.function.is_generator,
1475 is_async: m.function.is_async,
1476 decorators: None,
1477 return_type: m
1478 .function
1479 .return_type
1480 .as_ref()
1481 .map(|_| RawNode::null()),
1482 type_parameters: m
1483 .function
1484 .type_params
1485 .as_ref()
1486 .map(|_| RawNode::null()),
1487 predicate: None,
1488 }),
1489 swc::Prop::Assign(a) => {
1490 let ident = self.convert_ident_to_identifier(&a.key);
1491 ObjectExpressionProperty::ObjectProperty(ObjectProperty {
1492 base: self.make_base_node(a.span),
1493 key: Box::new(Expression::Identifier(ident.clone())),
1494 value: Box::new(Expression::AssignmentExpression(AssignmentExpression {
1495 base: self.make_base_node(a.span),
1496 operator: AssignmentOperator::Assign,
1497 left: Box::new(PatternLike::Identifier(ident)),
1498 right: Box::new(self.convert_expression(&a.value)),
1499 })),
1500 computed: false,
1501 shorthand: true,
1502 decorators: None,
1503 method: Some(false),
1504 })
1505 }
1506 }
1507 }
1508
1509 fn convert_array_expression(&self, arr: &swc::ArrayLit) -> ArrayExpression {
1510 ArrayExpression {
1511 base: self.make_base_node(arr.span),
1512 elements: arr
1513 .elems
1514 .iter()
1515 .map(|e| e.as_ref().map(|elem| self.convert_expr_or_spread(elem)))
1516 .collect(),
1517 }
1518 }
1519
1520 fn convert_template_literal(&self, tpl: &swc::Tpl) -> TemplateLiteral {
1521 TemplateLiteral {
1522 base: self.make_base_node(tpl.span),
1523 quasis: tpl
1524 .quasis
1525 .iter()
1526 .map(|q| TemplateElement {
1527 base: self.make_base_node(q.span),
1528 value: TemplateElementValue {
1529 raw: q.raw.to_string(),
1530 cooked: q.cooked.as_ref().map(|c| wtf8_to_string(c)),
1531 },
1532 tail: q.tail,
1533 })
1534 .collect(),
1535 expressions: tpl
1536 .exprs
1537 .iter()
1538 .map(|e| self.convert_expression(e))
1539 .collect(),
1540 }
1541 }
1542
1543 fn convert_class_decl(&self, class: &swc::ClassDecl) -> ClassDeclaration {
1546 let c = &class.class;
1547 ClassDeclaration {
1548 base: self.make_base_node(c.span),
1549 id: Some(self.convert_ident_to_identifier(&class.ident)),
1550 super_class: c
1551 .super_class
1552 .as_ref()
1553 .map(|s| Box::new(self.convert_expression(s))),
1554 body: ClassBody {
1555 base: self.make_base_node(c.span),
1556 body: vec![],
1557 },
1558 decorators: None,
1559 is_abstract: if c.is_abstract { Some(true) } else { None },
1560 declare: if class.declare { Some(true) } else { None },
1561 implements: None,
1562 super_type_parameters: None,
1563 type_parameters: c
1564 .type_params
1565 .as_ref()
1566 .map(|_| RawNode::null()),
1567 mixins: None,
1568 }
1569 }
1570
1571 fn convert_class_expression(&self, class: &swc::ClassExpr) -> ClassExpression {
1572 let c = &class.class;
1573 ClassExpression {
1574 base: self.make_base_node(c.span),
1575 id: class
1576 .ident
1577 .as_ref()
1578 .map(|id| self.convert_ident_to_identifier(id)),
1579 super_class: c
1580 .super_class
1581 .as_ref()
1582 .map(|s| Box::new(self.convert_expression(s))),
1583 body: ClassBody {
1584 base: self.make_base_node(c.span),
1585 body: vec![],
1586 },
1587 decorators: None,
1588 implements: None,
1589 super_type_parameters: None,
1590 type_parameters: c
1591 .type_params
1592 .as_ref()
1593 .map(|_| RawNode::null()),
1594 }
1595 }
1596
1597 fn convert_jsx_element(&self, el: &swc::JSXElement) -> JSXElement {
1600 let self_closing = el.closing.is_none();
1601 JSXElement {
1602 base: self.make_base_node(el.span),
1603 opening_element: self.convert_jsx_opening_element(&el.opening, self_closing),
1604 closing_element: el
1605 .closing
1606 .as_ref()
1607 .map(|c| self.convert_jsx_closing_element(c)),
1608 children: el
1609 .children
1610 .iter()
1611 .map(|c| self.convert_jsx_child(c))
1612 .collect(),
1613 self_closing: Some(self_closing),
1614 }
1615 }
1616
1617 fn convert_jsx_opening_element(
1618 &self,
1619 el: &swc::JSXOpeningElement,
1620 self_closing: bool,
1621 ) -> JSXOpeningElement {
1622 JSXOpeningElement {
1623 base: self.make_base_node(el.span),
1624 name: self.convert_jsx_element_name(&el.name),
1625 attributes: el
1626 .attrs
1627 .iter()
1628 .map(|a| self.convert_jsx_attr_or_spread(a))
1629 .collect(),
1630 self_closing,
1631 type_parameters: el
1632 .type_args
1633 .as_ref()
1634 .map(|_| RawNode::null()),
1635 }
1636 }
1637
1638 fn convert_jsx_closing_element(&self, el: &swc::JSXClosingElement) -> JSXClosingElement {
1639 JSXClosingElement {
1640 base: self.make_base_node(el.span),
1641 name: self.convert_jsx_element_name(&el.name),
1642 }
1643 }
1644
1645 fn convert_jsx_element_name(&self, name: &swc::JSXElementName) -> JSXElementName {
1646 match name {
1647 swc::JSXElementName::Ident(id) => JSXElementName::JSXIdentifier(JSXIdentifier {
1648 base: self.make_base_node(id.span),
1649 name: id.sym.to_string(),
1650 }),
1651 swc::JSXElementName::JSXMemberExpr(m) => {
1652 JSXElementName::JSXMemberExpression(self.convert_jsx_member_expression(m))
1653 }
1654 swc::JSXElementName::JSXNamespacedName(ns) => {
1655 JSXElementName::JSXNamespacedName(JSXNamespacedName {
1656 base: self.make_base_node(ns.span()),
1657 namespace: JSXIdentifier {
1658 base: self.make_base_node(ns.ns.span),
1659 name: ns.ns.sym.to_string(),
1660 },
1661 name: JSXIdentifier {
1662 base: self.make_base_node(ns.name.span),
1663 name: ns.name.sym.to_string(),
1664 },
1665 })
1666 }
1667 }
1668 }
1669
1670 fn convert_jsx_member_expression(&self, m: &swc::JSXMemberExpr) -> JSXMemberExpression {
1671 JSXMemberExpression {
1672 base: self.make_base_node(m.span()),
1673 object: Box::new(self.convert_jsx_object(&m.obj)),
1674 property: JSXIdentifier {
1675 base: self.make_base_node(m.prop.span),
1676 name: m.prop.sym.to_string(),
1677 },
1678 }
1679 }
1680
1681 fn convert_jsx_object(&self, obj: &swc::JSXObject) -> JSXMemberExprObject {
1682 match obj {
1683 swc::JSXObject::Ident(id) => JSXMemberExprObject::JSXIdentifier(JSXIdentifier {
1684 base: self.make_base_node(id.span),
1685 name: id.sym.to_string(),
1686 }),
1687 swc::JSXObject::JSXMemberExpr(m) => JSXMemberExprObject::JSXMemberExpression(Box::new(
1688 self.convert_jsx_member_expression(m),
1689 )),
1690 }
1691 }
1692
1693 fn convert_jsx_attr_or_spread(&self, attr: &swc::JSXAttrOrSpread) -> JSXAttributeItem {
1694 match attr {
1695 swc::JSXAttrOrSpread::JSXAttr(a) => {
1696 JSXAttributeItem::JSXAttribute(self.convert_jsx_attribute(a))
1697 }
1698 swc::JSXAttrOrSpread::SpreadElement(s) => {
1699 JSXAttributeItem::JSXSpreadAttribute(JSXSpreadAttribute {
1700 base: self.make_base_node(s.span()),
1701 argument: Box::new(self.convert_expression(&s.expr)),
1702 })
1703 }
1704 }
1705 }
1706
1707 fn convert_jsx_attribute(&self, attr: &swc::JSXAttr) -> JSXAttribute {
1708 JSXAttribute {
1709 base: self.make_base_node(attr.span),
1710 name: self.convert_jsx_attr_name(&attr.name),
1711 value: attr.value.as_ref().map(|v| self.convert_jsx_attr_value(v)),
1712 }
1713 }
1714
1715 fn convert_jsx_attr_name(&self, name: &swc::JSXAttrName) -> JSXAttributeName {
1716 match name {
1717 swc::JSXAttrName::Ident(id) => JSXAttributeName::JSXIdentifier(JSXIdentifier {
1718 base: self.make_base_node(id.span),
1719 name: id.sym.to_string(),
1720 }),
1721 swc::JSXAttrName::JSXNamespacedName(ns) => {
1722 JSXAttributeName::JSXNamespacedName(JSXNamespacedName {
1723 base: self.make_base_node(ns.span()),
1724 namespace: JSXIdentifier {
1725 base: self.make_base_node(ns.ns.span),
1726 name: ns.ns.sym.to_string(),
1727 },
1728 name: JSXIdentifier {
1729 base: self.make_base_node(ns.name.span),
1730 name: ns.name.sym.to_string(),
1731 },
1732 })
1733 }
1734 }
1735 }
1736
1737 fn convert_jsx_attr_value(&self, value: &swc::JSXAttrValue) -> JSXAttributeValue {
1738 match value {
1739 swc::JSXAttrValue::Str(s) => JSXAttributeValue::StringLiteral(StringLiteral {
1740 base: self.make_base_node(s.span),
1741 value: wtf8_to_string(&s.value),
1742 }),
1743 swc::JSXAttrValue::JSXExprContainer(ec) => {
1744 JSXAttributeValue::JSXExpressionContainer(self.convert_jsx_expr_container(ec))
1745 }
1746 swc::JSXAttrValue::JSXElement(el) => {
1747 JSXAttributeValue::JSXElement(Box::new(self.convert_jsx_element(el)))
1748 }
1749 swc::JSXAttrValue::JSXFragment(frag) => {
1750 JSXAttributeValue::JSXFragment(self.convert_jsx_fragment(frag))
1751 }
1752 }
1753 }
1754
1755 fn convert_jsx_expr_container(&self, ec: &swc::JSXExprContainer) -> JSXExpressionContainer {
1756 JSXExpressionContainer {
1757 base: self.make_base_node(ec.span),
1758 expression: match &ec.expr {
1759 swc::JSXExpr::JSXEmptyExpr(e) => {
1760 JSXExpressionContainerExpr::JSXEmptyExpression(JSXEmptyExpression {
1761 base: self.make_base_node(e.span),
1762 })
1763 }
1764 swc::JSXExpr::Expr(e) => {
1765 JSXExpressionContainerExpr::Expression(Box::new(self.convert_expression(e)))
1766 }
1767 },
1768 }
1769 }
1770
1771 fn convert_jsx_child(&self, child: &swc::JSXElementChild) -> JSXChild {
1772 match child {
1773 swc::JSXElementChild::JSXText(t) => JSXChild::JSXText(JSXText {
1774 base: self.make_base_node(t.span),
1775 value: t.value.to_string(),
1776 }),
1777 swc::JSXElementChild::JSXExprContainer(ec) => {
1778 JSXChild::JSXExpressionContainer(self.convert_jsx_expr_container(ec))
1779 }
1780 swc::JSXElementChild::JSXSpreadChild(s) => JSXChild::JSXSpreadChild(JSXSpreadChild {
1781 base: self.make_base_node(s.span),
1782 expression: Box::new(self.convert_expression(&s.expr)),
1783 }),
1784 swc::JSXElementChild::JSXElement(el) => {
1785 JSXChild::JSXElement(Box::new(self.convert_jsx_element(el)))
1786 }
1787 swc::JSXElementChild::JSXFragment(frag) => {
1788 JSXChild::JSXFragment(self.convert_jsx_fragment(frag))
1789 }
1790 }
1791 }
1792
1793 fn convert_jsx_fragment(&self, frag: &swc::JSXFragment) -> JSXFragment {
1794 JSXFragment {
1795 base: self.make_base_node(frag.span),
1796 opening_fragment: JSXOpeningFragment {
1797 base: self.make_base_node(frag.opening.span),
1798 },
1799 closing_fragment: JSXClosingFragment {
1800 base: self.make_base_node(frag.closing.span),
1801 },
1802 children: frag
1803 .children
1804 .iter()
1805 .map(|c| self.convert_jsx_child(c))
1806 .collect(),
1807 }
1808 }
1809
1810 fn convert_import_declaration(&self, decl: &swc::ImportDecl) -> ImportDeclaration {
1813 ImportDeclaration {
1814 base: self.make_base_node(decl.span),
1815 specifiers: decl
1816 .specifiers
1817 .iter()
1818 .map(|s| self.convert_import_specifier(s))
1819 .collect(),
1820 source: StringLiteral {
1821 base: self.make_base_node(decl.src.span),
1822 value: wtf8_to_string(&decl.src.value),
1823 },
1824 import_kind: if decl.type_only {
1825 Some(ImportKind::Type)
1826 } else {
1827 Some(ImportKind::Value)
1828 },
1829 assertions: None,
1830 attributes: decl
1831 .with
1832 .as_ref()
1833 .map(|with| self.convert_object_lit_to_import_attributes(with)),
1834 }
1835 }
1836
1837 fn convert_object_lit_to_import_attributes(
1838 &self,
1839 obj: &swc::ObjectLit,
1840 ) -> Vec<ImportAttribute> {
1841 obj.props
1842 .iter()
1843 .filter_map(|prop| {
1844 if let swc::PropOrSpread::Prop(p) = prop {
1845 if let swc::Prop::KeyValue(kv) = &**p {
1846 let (key_name, key_span) = match &kv.key {
1847 swc::PropName::Ident(id) => (id.sym.to_string(), id.span),
1848 swc::PropName::Str(s) => (wtf8_to_string(&s.value), s.span),
1849 swc::PropName::Num(n) => (n.value.to_string(), n.span),
1850 _ => return None,
1851 };
1852 if let swc::Expr::Lit(swc::Lit::Str(s)) = &*kv.value {
1853 return Some(ImportAttribute {
1854 base: self.make_base_node(kv.span()),
1855 key: Identifier {
1856 base: self.make_base_node(key_span),
1857 name: key_name,
1858 type_annotation: None,
1859 optional: None,
1860 decorators: None,
1861 },
1862 value: StringLiteral {
1863 base: self.make_base_node(s.span),
1864 value: wtf8_to_string(&s.value),
1865 },
1866 });
1867 }
1868 }
1869 }
1870 None
1871 })
1872 .collect()
1873 }
1874
1875 fn convert_import_specifier(&self, spec: &swc::ImportSpecifier) -> ImportSpecifier {
1876 match spec {
1877 swc::ImportSpecifier::Named(s) => {
1878 let local = self.convert_ident_to_identifier(&s.local);
1879 let imported = s
1880 .imported
1881 .as_ref()
1882 .map(|i| match i {
1883 swc::ModuleExportName::Ident(id) => {
1884 ModuleExportName::Identifier(self.convert_ident_to_identifier(id))
1885 }
1886 swc::ModuleExportName::Str(s) => {
1887 ModuleExportName::StringLiteral(StringLiteral {
1888 base: self.make_base_node(s.span),
1889 value: wtf8_to_string(&s.value),
1890 })
1891 }
1892 })
1893 .unwrap_or_else(|| ModuleExportName::Identifier(local.clone()));
1894 ImportSpecifier::ImportSpecifier(ImportSpecifierData {
1895 base: self.make_base_node(s.span),
1896 local,
1897 imported,
1898 import_kind: if s.is_type_only {
1899 Some(ImportKind::Type)
1900 } else {
1901 Some(ImportKind::Value)
1902 },
1903 })
1904 }
1905 swc::ImportSpecifier::Default(s) => {
1906 ImportSpecifier::ImportDefaultSpecifier(ImportDefaultSpecifierData {
1907 base: self.make_base_node(s.span),
1908 local: self.convert_ident_to_identifier(&s.local),
1909 })
1910 }
1911 swc::ImportSpecifier::Namespace(s) => {
1912 ImportSpecifier::ImportNamespaceSpecifier(ImportNamespaceSpecifierData {
1913 base: self.make_base_node(s.span),
1914 local: self.convert_ident_to_identifier(&s.local),
1915 })
1916 }
1917 }
1918 }
1919
1920 fn convert_export_decl(&self, decl: &swc::ExportDecl) -> ExportNamedDeclaration {
1921 ExportNamedDeclaration {
1922 base: self.make_base_node(decl.span),
1923 declaration: Some(Box::new(self.convert_decl_to_declaration(&decl.decl))),
1924 specifiers: vec![],
1925 source: None,
1926 export_kind: Some(ExportKind::Value),
1927 assertions: None,
1928 attributes: None,
1929 }
1930 }
1931
1932 fn convert_export_named(&self, decl: &swc::NamedExport) -> ExportNamedDeclaration {
1933 ExportNamedDeclaration {
1934 base: self.make_base_node(decl.span),
1935 declaration: None,
1936 specifiers: decl
1937 .specifiers
1938 .iter()
1939 .map(|s| self.convert_export_specifier(s))
1940 .collect(),
1941 source: decl.src.as_ref().map(|s| StringLiteral {
1942 base: self.make_base_node(s.span),
1943 value: wtf8_to_string(&s.value),
1944 }),
1945 export_kind: if decl.type_only {
1946 Some(ExportKind::Type)
1947 } else {
1948 Some(ExportKind::Value)
1949 },
1950 assertions: None,
1951 attributes: decl
1952 .with
1953 .as_ref()
1954 .map(|with| self.convert_object_lit_to_import_attributes(with)),
1955 }
1956 }
1957
1958 fn convert_export_default_decl(
1959 &self,
1960 decl: &swc::ExportDefaultDecl,
1961 ) -> ExportDefaultDeclaration {
1962 let declaration = match &decl.decl {
1963 swc::DefaultDecl::Fn(f) => {
1964 let func = &f.function;
1965 let body = func
1966 .body
1967 .as_ref()
1968 .map(|b| self.convert_block_statement(b))
1969 .unwrap_or_else(|| BlockStatement {
1970 base: self.make_base_node(func.span),
1971 body: vec![],
1972 directives: vec![],
1973 });
1974 ExportDefaultDecl::FunctionDeclaration(FunctionDeclaration {
1975 base: self.make_base_node(func.span),
1976 id: f
1977 .ident
1978 .as_ref()
1979 .map(|id| self.convert_ident_to_identifier(id)),
1980 params: self.convert_params(&func.params),
1981 body,
1982 generator: func.is_generator,
1983 is_async: func.is_async,
1984 declare: None,
1985 return_type: func
1986 .return_type
1987 .as_ref()
1988 .map(|_| RawNode::null()),
1989 type_parameters: func
1990 .type_params
1991 .as_ref()
1992 .map(|_| RawNode::null()),
1993 predicate: None,
1994 component_declaration: false,
1995 hook_declaration: false,
1996 })
1997 }
1998 swc::DefaultDecl::Class(c) => {
1999 let class = &c.class;
2000 ExportDefaultDecl::ClassDeclaration(ClassDeclaration {
2001 base: self.make_base_node(class.span),
2002 id: c
2003 .ident
2004 .as_ref()
2005 .map(|id| self.convert_ident_to_identifier(id)),
2006 super_class: class
2007 .super_class
2008 .as_ref()
2009 .map(|s| Box::new(self.convert_expression(s))),
2010 body: ClassBody {
2011 base: self.make_base_node(class.span),
2012 body: vec![],
2013 },
2014 decorators: None,
2015 is_abstract: if class.is_abstract { Some(true) } else { None },
2016 declare: None,
2017 implements: None,
2018 super_type_parameters: None,
2019 type_parameters: class
2020 .type_params
2021 .as_ref()
2022 .map(|_| RawNode::null()),
2023 mixins: None,
2024 })
2025 }
2026 swc::DefaultDecl::TsInterfaceDecl(_) => {
2027 ExportDefaultDecl::Expression(Box::new(Expression::NullLiteral(NullLiteral {
2028 base: self.make_base_node(decl.span),
2029 })))
2030 }
2031 };
2032 ExportDefaultDeclaration {
2033 base: self.make_base_node(decl.span),
2034 declaration: Box::new(declaration),
2035 export_kind: None,
2036 }
2037 }
2038
2039 fn convert_export_default_expr(
2040 &self,
2041 decl: &swc::ExportDefaultExpr,
2042 ) -> ExportDefaultDeclaration {
2043 ExportDefaultDeclaration {
2044 base: self.make_base_node(decl.span),
2045 declaration: Box::new(ExportDefaultDecl::Expression(Box::new(
2046 self.convert_expression(&decl.expr),
2047 ))),
2048 export_kind: None,
2049 }
2050 }
2051
2052 fn convert_export_all(&self, decl: &swc::ExportAll) -> ExportAllDeclaration {
2053 ExportAllDeclaration {
2054 base: self.make_base_node(decl.span),
2055 source: StringLiteral {
2056 base: self.make_base_node(decl.src.span),
2057 value: wtf8_to_string(&decl.src.value),
2058 },
2059 export_kind: if decl.type_only {
2060 Some(ExportKind::Type)
2061 } else {
2062 Some(ExportKind::Value)
2063 },
2064 assertions: None,
2065 attributes: decl
2066 .with
2067 .as_ref()
2068 .map(|with| self.convert_object_lit_to_import_attributes(with)),
2069 }
2070 }
2071
2072 fn convert_decl_to_declaration(&self, decl: &swc::Decl) -> Declaration {
2073 match decl {
2074 swc::Decl::Var(v) => {
2075 Declaration::VariableDeclaration(self.convert_variable_declaration(v))
2076 }
2077 swc::Decl::Fn(f) => Declaration::FunctionDeclaration(self.convert_fn_decl(f)),
2078 swc::Decl::Class(c) => Declaration::ClassDeclaration(self.convert_class_decl(c)),
2079 swc::Decl::TsTypeAlias(d) => {
2080 Declaration::TSTypeAliasDeclaration(self.convert_ts_type_alias(d))
2081 }
2082 swc::Decl::TsInterface(d) => {
2083 Declaration::TSInterfaceDeclaration(self.convert_ts_interface(d))
2084 }
2085 swc::Decl::TsEnum(d) => Declaration::TSEnumDeclaration(self.convert_ts_enum(d)),
2086 swc::Decl::TsModule(d) => Declaration::TSModuleDeclaration(self.convert_ts_module(d)),
2087 swc::Decl::Using(u) => Declaration::VariableDeclaration(self.convert_using_decl(u)),
2088 }
2089 }
2090
2091 fn convert_export_specifier(&self, spec: &swc::ExportSpecifier) -> ExportSpecifier {
2092 match spec {
2093 swc::ExportSpecifier::Named(s) => {
2094 let local = self.convert_module_export_name(&s.orig);
2095 let exported = s
2096 .exported
2097 .as_ref()
2098 .map(|e| self.convert_module_export_name(e))
2099 .unwrap_or_else(|| local.clone());
2100 ExportSpecifier::ExportSpecifier(ExportSpecifierData {
2101 base: self.make_base_node(s.span),
2102 local,
2103 exported,
2104 export_kind: if s.is_type_only {
2105 Some(ExportKind::Type)
2106 } else {
2107 Some(ExportKind::Value)
2108 },
2109 })
2110 }
2111 swc::ExportSpecifier::Default(s) => {
2112 ExportSpecifier::ExportDefaultSpecifier(ExportDefaultSpecifierData {
2113 base: self.make_base_node(s.exported.span),
2114 exported: self.convert_ident_to_identifier(&s.exported),
2115 })
2116 }
2117 swc::ExportSpecifier::Namespace(s) => {
2118 ExportSpecifier::ExportNamespaceSpecifier(ExportNamespaceSpecifierData {
2119 base: self.make_base_node(s.span),
2120 exported: self.convert_module_export_name(&s.name),
2121 })
2122 }
2123 }
2124 }
2125
2126 fn convert_module_export_name(&self, name: &swc::ModuleExportName) -> ModuleExportName {
2127 match name {
2128 swc::ModuleExportName::Ident(id) => {
2129 ModuleExportName::Identifier(self.convert_ident_to_identifier(id))
2130 }
2131 swc::ModuleExportName::Str(s) => ModuleExportName::StringLiteral(StringLiteral {
2132 base: self.make_base_node(s.span),
2133 value: wtf8_to_string(&s.value),
2134 }),
2135 }
2136 }
2137
2138 fn convert_ts_type_alias(&self, d: &swc::TsTypeAliasDecl) -> TSTypeAliasDeclaration {
2141 TSTypeAliasDeclaration {
2142 base: self.make_base_node(d.span),
2143 id: self.convert_ident_to_identifier(&d.id),
2144 type_annotation: RawNode::null(),
2145 type_parameters: d
2146 .type_params
2147 .as_ref()
2148 .map(|_| RawNode::null()),
2149 declare: if d.declare { Some(true) } else { None },
2150 }
2151 }
2152
2153 fn convert_ts_interface(&self, d: &swc::TsInterfaceDecl) -> TSInterfaceDeclaration {
2154 TSInterfaceDeclaration {
2155 base: self.make_base_node(d.span),
2156 id: self.convert_ident_to_identifier(&d.id),
2157 body: RawNode::null(),
2158 type_parameters: d
2159 .type_params
2160 .as_ref()
2161 .map(|_| RawNode::null()),
2162 extends: if d.extends.is_empty() {
2163 None
2164 } else {
2165 Some(vec![])
2166 },
2167 declare: if d.declare { Some(true) } else { None },
2168 }
2169 }
2170
2171 fn convert_ts_enum(&self, d: &swc::TsEnumDecl) -> TSEnumDeclaration {
2172 TSEnumDeclaration {
2173 base: self.make_base_node(d.span),
2174 id: self.convert_ident_to_identifier(&d.id),
2175 members: vec![],
2176 declare: if d.declare { Some(true) } else { None },
2177 is_const: if d.is_const { Some(true) } else { None },
2178 }
2179 }
2180
2181 fn convert_ts_module(&self, d: &swc::TsModuleDecl) -> TSModuleDeclaration {
2182 TSModuleDeclaration {
2183 base: self.make_base_node(d.span),
2184 id: RawNode::null(),
2185 body: RawNode::null(),
2186 declare: if d.declare { Some(true) } else { None },
2187 global: if d.global { Some(true) } else { None },
2188 }
2189 }
2190
2191 fn convert_ts_type_to_json(&self, ty: &swc::TsType) -> Option<serde_json::Value> {
2194 match ty {
2195 swc::TsType::TsKeywordType(k) if k.kind == swc::TsKeywordTypeKind::TsNumberKeyword => {
2196 Some(serde_json::json!({ "type": "TSNumberKeyword" }))
2197 }
2198 swc::TsType::TsTypeRef(r) if r.type_params.is_none() => match &r.type_name {
2202 swc::TsEntityName::Ident(id) => Some(serde_json::json!({
2203 "type": "TSTypeReference",
2204 "typeName": {
2205 "type": "Identifier",
2206 "name": id.sym.to_string()
2207 }
2208 })),
2209 _ => None,
2210 },
2211 _ => None,
2212 }
2213 }
2214
2215 fn convert_ts_type_ann_to_json(&self, ann: &swc::TsTypeAnn) -> Option<serde_json::Value> {
2216 Some(serde_json::json!({
2217 "type": "TSTypeAnnotation",
2218 "typeAnnotation": self.convert_ts_type_to_json(&ann.type_ann)?,
2219 }))
2220 }
2221
2222 fn convert_ident_to_identifier(&self, id: &swc::Ident) -> Identifier {
2225 Identifier {
2226 base: self.make_base_node(id.span),
2227 name: id.sym.to_string(),
2228 type_annotation: None,
2229 optional: if id.optional { Some(true) } else { None },
2230 decorators: None,
2231 }
2232 }
2233
2234 fn convert_binding_ident(&self, id: &swc::BindingIdent) -> Identifier {
2235 Identifier {
2236 base: self.make_base_node(id.id.span),
2237 name: id.id.sym.to_string(),
2238 type_annotation: id.type_ann.as_ref().map(|ann| {
2239 RawNode::from_value(
2240 &self
2241 .convert_ts_type_ann_to_json(ann)
2242 .unwrap_or(serde_json::Value::Null),
2243 )
2244 }),
2245 optional: if id.id.optional { Some(true) } else { None },
2246 decorators: None,
2247 }
2248 }
2249
2250 fn convert_prop_name(&self, key: &swc::PropName) -> Expression {
2251 match key {
2252 swc::PropName::Ident(id) => Expression::Identifier(Identifier {
2253 base: self.make_base_node(id.span),
2254 name: id.sym.to_string(),
2255 type_annotation: None,
2256 optional: None,
2257 decorators: None,
2258 }),
2259 swc::PropName::Str(s) => Expression::StringLiteral(StringLiteral {
2260 base: self.make_base_node(s.span),
2261 value: wtf8_to_string(&s.value),
2262 }),
2263 swc::PropName::Num(n) => Expression::NumericLiteral(NumericLiteral {
2264 base: self.make_base_node(n.span),
2265 value: n.value,
2266 extra: None,
2267 }),
2268 swc::PropName::Computed(c) => self.convert_expression(&c.expr),
2269 swc::PropName::BigInt(b) => Expression::BigIntLiteral(BigIntLiteral {
2270 base: self.make_base_node(b.span),
2271 value: b.value.to_string(),
2272 }),
2273 }
2274 }
2275
2276 fn convert_binary_operator(&self, op: swc::BinaryOp) -> BinaryOperator {
2279 match op {
2280 swc::BinaryOp::EqEq => BinaryOperator::Eq,
2281 swc::BinaryOp::NotEq => BinaryOperator::Neq,
2282 swc::BinaryOp::EqEqEq => BinaryOperator::StrictEq,
2283 swc::BinaryOp::NotEqEq => BinaryOperator::StrictNeq,
2284 swc::BinaryOp::Lt => BinaryOperator::Lt,
2285 swc::BinaryOp::LtEq => BinaryOperator::Lte,
2286 swc::BinaryOp::Gt => BinaryOperator::Gt,
2287 swc::BinaryOp::GtEq => BinaryOperator::Gte,
2288 swc::BinaryOp::LShift => BinaryOperator::Shl,
2289 swc::BinaryOp::RShift => BinaryOperator::Shr,
2290 swc::BinaryOp::ZeroFillRShift => BinaryOperator::UShr,
2291 swc::BinaryOp::Add => BinaryOperator::Add,
2292 swc::BinaryOp::Sub => BinaryOperator::Sub,
2293 swc::BinaryOp::Mul => BinaryOperator::Mul,
2294 swc::BinaryOp::Div => BinaryOperator::Div,
2295 swc::BinaryOp::Mod => BinaryOperator::Rem,
2296 swc::BinaryOp::Exp => BinaryOperator::Exp,
2297 swc::BinaryOp::BitOr => BinaryOperator::BitOr,
2298 swc::BinaryOp::BitXor => BinaryOperator::BitXor,
2299 swc::BinaryOp::BitAnd => BinaryOperator::BitAnd,
2300 swc::BinaryOp::In => BinaryOperator::In,
2301 swc::BinaryOp::InstanceOf => BinaryOperator::Instanceof,
2302 swc::BinaryOp::LogicalOr
2303 | swc::BinaryOp::LogicalAnd
2304 | swc::BinaryOp::NullishCoalescing => BinaryOperator::Eq,
2305 }
2306 }
2307
2308 fn try_convert_logical_operator(&self, op: swc::BinaryOp) -> Option<LogicalOperator> {
2309 match op {
2310 swc::BinaryOp::LogicalOr => Some(LogicalOperator::Or),
2311 swc::BinaryOp::LogicalAnd => Some(LogicalOperator::And),
2312 swc::BinaryOp::NullishCoalescing => Some(LogicalOperator::NullishCoalescing),
2313 _ => None,
2314 }
2315 }
2316
2317 fn convert_unary_operator(&self, op: swc::UnaryOp) -> UnaryOperator {
2318 match op {
2319 swc::UnaryOp::Minus => UnaryOperator::Neg,
2320 swc::UnaryOp::Plus => UnaryOperator::Plus,
2321 swc::UnaryOp::Bang => UnaryOperator::Not,
2322 swc::UnaryOp::Tilde => UnaryOperator::BitNot,
2323 swc::UnaryOp::TypeOf => UnaryOperator::TypeOf,
2324 swc::UnaryOp::Void => UnaryOperator::Void,
2325 swc::UnaryOp::Delete => UnaryOperator::Delete,
2326 }
2327 }
2328
2329 fn convert_update_operator(&self, op: swc::UpdateOp) -> UpdateOperator {
2330 match op {
2331 swc::UpdateOp::PlusPlus => UpdateOperator::Increment,
2332 swc::UpdateOp::MinusMinus => UpdateOperator::Decrement,
2333 }
2334 }
2335
2336 fn convert_assignment_operator(&self, op: swc::AssignOp) -> AssignmentOperator {
2337 match op {
2338 swc::AssignOp::Assign => AssignmentOperator::Assign,
2339 swc::AssignOp::AddAssign => AssignmentOperator::AddAssign,
2340 swc::AssignOp::SubAssign => AssignmentOperator::SubAssign,
2341 swc::AssignOp::MulAssign => AssignmentOperator::MulAssign,
2342 swc::AssignOp::DivAssign => AssignmentOperator::DivAssign,
2343 swc::AssignOp::ModAssign => AssignmentOperator::RemAssign,
2344 swc::AssignOp::ExpAssign => AssignmentOperator::ExpAssign,
2345 swc::AssignOp::LShiftAssign => AssignmentOperator::ShlAssign,
2346 swc::AssignOp::RShiftAssign => AssignmentOperator::ShrAssign,
2347 swc::AssignOp::ZeroFillRShiftAssign => AssignmentOperator::UShrAssign,
2348 swc::AssignOp::BitOrAssign => AssignmentOperator::BitOrAssign,
2349 swc::AssignOp::BitXorAssign => AssignmentOperator::BitXorAssign,
2350 swc::AssignOp::BitAndAssign => AssignmentOperator::BitAndAssign,
2351 swc::AssignOp::OrAssign => AssignmentOperator::OrAssign,
2352 swc::AssignOp::AndAssign => AssignmentOperator::AndAssign,
2353 swc::AssignOp::NullishAssign => AssignmentOperator::NullishAssign,
2354 }
2355 }
2356}