1use std::collections::{HashMap, HashSet};
15
16use react_compiler_ast::common::SourceLocation as AstSourceLocation;
17use react_compiler_ast::expressions::{
18 ArrowFunctionBody, ArrowFunctionExpression, Expression, FunctionExpression,
19 ObjectExpressionProperty,
20};
21use react_compiler_ast::patterns::PatternLike;
22use react_compiler_ast::statements::{ForInit, ForInOfLeft, Statement, VariableDeclaration};
23use react_compiler_diagnostics::{
24 CompilerDiagnostic, CompilerDiagnosticDetail, ErrorCategory,
25 SourceLocation as DiagSourceLocation, Position as DiagPosition,
26};
27use react_compiler_hir::environment::Environment;
28use react_compiler_lowering::FunctionNode;
29use react_compiler_reactive_scopes::codegen_reactive_function::CodegenFunction;
30
31pub fn validate_source_locations(
33 func: &FunctionNode<'_>,
34 codegen: &CodegenFunction,
35 env: &mut Environment,
36) {
37 let important_original = collect_important_original_locations(func);
39
40 let mut generated = HashMap::<String, HashSet<String>>::new();
42 collect_generated_from_block(&codegen.body.body, &mut generated);
43 for outlined in &codegen.outlined {
44 collect_generated_from_block(&outlined.func.body.body, &mut generated);
45 }
46
47 let strict_node_types: HashSet<&str> =
49 ["VariableDeclaration", "VariableDeclarator", "Identifier"]
50 .into_iter()
51 .collect();
52
53 let mut sorted_entries: Vec<&ImportantLocation> = important_original.values().collect();
56 sorted_entries.sort_by(|a, b| {
57 a.loc.start.line.cmp(&b.loc.start.line)
58 .then(a.loc.start.column.cmp(&b.loc.start.column))
59 .then(b.loc.end.line.cmp(&a.loc.end.line))
61 .then(b.loc.end.column.cmp(&a.loc.end.column))
62 });
63
64 for entry in &sorted_entries {
65 let generated_node_types = generated.get(&entry.key);
66
67 if generated_node_types.is_none() {
68 let mut node_types_str: Vec<&str> = entry.node_types.iter().copied().collect();
70 node_types_str.sort();
71 report_missing_location(env, &entry.loc, &node_types_str.join(", "));
72 } else {
73 let generated_node_types = generated_node_types.unwrap();
74 for &node_type in &entry.node_types {
76 if strict_node_types.contains(node_type)
77 && !generated_node_types.contains(node_type)
78 {
79 let has_valid_node_type = generated_node_types
82 .iter()
83 .any(|gen_type| entry.node_types.contains(gen_type.as_str()));
84
85 if has_valid_node_type {
86 report_missing_location(env, &entry.loc, node_type);
87 } else {
88 report_wrong_node_type(
89 env,
90 &entry.loc,
91 node_type,
92 generated_node_types,
93 );
94 }
95 }
96 }
97 }
98 }
99}
100
101struct ImportantLocation {
104 key: String,
105 loc: AstSourceLocation,
106 node_types: HashSet<&'static str>,
107}
108
109fn location_key(loc: &AstSourceLocation) -> String {
112 format!(
113 "{}:{}-{}:{}",
114 loc.start.line, loc.start.column, loc.end.line, loc.end.column
115 )
116}
117
118fn ast_to_diag_loc(loc: &AstSourceLocation) -> DiagSourceLocation {
121 DiagSourceLocation {
122 start: DiagPosition {
123 line: loc.start.line,
124 column: loc.start.column,
125 index: loc.start.index,
126 },
127 end: DiagPosition {
128 line: loc.end.line,
129 column: loc.end.column,
130 index: loc.end.index,
131 },
132 }
133}
134
135fn report_missing_location(env: &mut Environment, loc: &AstSourceLocation, node_type: &str) {
138 let diag_loc = ast_to_diag_loc(loc);
139 env.record_diagnostic(
140 CompilerDiagnostic::new(
141 ErrorCategory::Todo,
142 "Important source location missing in generated code",
143 Some(format!(
144 "Source location for {} is missing in the generated output. \
145 This can cause coverage instrumentation to fail to track this \
146 code properly, resulting in inaccurate coverage reports.",
147 node_type
148 )),
149 )
150 .with_detail(CompilerDiagnosticDetail::Error {
151 loc: Some(diag_loc),
152 message: None,
153 identifier_name: None,
154 }),
155 );
156}
157
158fn report_wrong_node_type(
159 env: &mut Environment,
160 loc: &AstSourceLocation,
161 expected_type: &str,
162 actual_types: &HashSet<String>,
163) {
164 let diag_loc = ast_to_diag_loc(loc);
165 let mut actual: Vec<&str> = actual_types.iter().map(|s| s.as_str()).collect();
166 actual.sort();
167 env.record_diagnostic(
168 CompilerDiagnostic::new(
169 ErrorCategory::Todo,
170 "Important source location has wrong node type in generated code",
171 Some(format!(
172 "Source location for {} exists in the generated output but with wrong \
173 node type(s): {}. This can cause coverage instrumentation to fail to \
174 track this code properly, resulting in inaccurate coverage reports.",
175 expected_type,
176 actual.join(", ")
177 )),
178 )
179 .with_detail(CompilerDiagnosticDetail::Error {
180 loc: Some(diag_loc),
181 message: None,
182 identifier_name: None,
183 }),
184 );
185}
186
187fn important_statement_type(stmt: &Statement) -> Option<&'static str> {
191 match stmt {
192 Statement::ExpressionStatement(_) => Some("ExpressionStatement"),
193 Statement::BreakStatement(_) => Some("BreakStatement"),
194 Statement::ContinueStatement(_) => Some("ContinueStatement"),
195 Statement::ReturnStatement(_) => Some("ReturnStatement"),
196 Statement::ThrowStatement(_) => Some("ThrowStatement"),
197 Statement::TryStatement(_) => Some("TryStatement"),
198 Statement::IfStatement(_) => Some("IfStatement"),
199 Statement::ForStatement(_) => Some("ForStatement"),
200 Statement::ForInStatement(_) => Some("ForInStatement"),
201 Statement::ForOfStatement(_) => Some("ForOfStatement"),
202 Statement::WhileStatement(_) => Some("WhileStatement"),
203 Statement::DoWhileStatement(_) => Some("DoWhileStatement"),
204 Statement::SwitchStatement(_) => Some("SwitchStatement"),
205 Statement::WithStatement(_) => Some("WithStatement"),
206 Statement::FunctionDeclaration(_) => Some("FunctionDeclaration"),
207 Statement::LabeledStatement(_) => Some("LabeledStatement"),
208 Statement::VariableDeclaration(_) => Some("VariableDeclaration"),
209 _ => None,
210 }
211}
212
213fn important_expression_type(expr: &Expression) -> Option<&'static str> {
215 match expr {
216 Expression::ArrowFunctionExpression(_) => Some("ArrowFunctionExpression"),
217 Expression::FunctionExpression(_) => Some("FunctionExpression"),
218 Expression::ConditionalExpression(_) => Some("ConditionalExpression"),
219 Expression::LogicalExpression(_) => Some("LogicalExpression"),
220 Expression::Identifier(_) => Some("Identifier"),
221 Expression::AssignmentPattern(_) => Some("AssignmentPattern"),
222 _ => None,
223 }
224}
225
226fn is_manual_memoization(expr: &Expression) -> bool {
229 if let Expression::CallExpression(call) = expr {
230 match call.callee.as_ref() {
231 Expression::Identifier(id) => {
232 id.name == "useMemo" || id.name == "useCallback"
233 }
234 Expression::MemberExpression(mem) => {
235 if let (Expression::Identifier(obj), Expression::Identifier(prop)) =
236 (mem.object.as_ref(), &*mem.property)
237 {
238 obj.name == "React"
239 && (prop.name == "useMemo" || prop.name == "useCallback")
240 } else {
241 false
242 }
243 }
244 _ => false,
245 }
246 } else {
247 false
248 }
249}
250
251fn collect_important_original_locations(
256 func: &FunctionNode<'_>,
257) -> HashMap<String, ImportantLocation> {
258 let mut locations = HashMap::new();
259
260 match func {
263 FunctionNode::FunctionDeclaration(f) => {
264 if let Some(id) = &f.id {
265 record_important("Identifier", &id.base.loc, &mut locations);
266 }
267 for param in &f.params {
268 collect_original_pattern(param, &mut locations);
269 }
270 collect_original_block(&f.body.body, false, &mut locations);
271 }
272 FunctionNode::FunctionExpression(f) => {
273 if let Some(id) = &f.id {
274 record_important("Identifier", &id.base.loc, &mut locations);
275 }
276 for param in &f.params {
277 collect_original_pattern(param, &mut locations);
278 }
279 collect_original_block(&f.body.body, false, &mut locations);
280 }
281 FunctionNode::ArrowFunctionExpression(f) => {
282 for param in &f.params {
283 collect_original_pattern(param, &mut locations);
284 }
285 match f.body.as_ref() {
286 ArrowFunctionBody::BlockStatement(block) => {
287 collect_original_block(&block.body, false, &mut locations);
288 }
289 ArrowFunctionBody::Expression(expr) => {
290 collect_original_expression(expr, &mut locations);
291 }
292 }
293 }
294 }
295
296 locations
297}
298
299fn record_important(
300 node_type: &'static str,
301 loc: &Option<AstSourceLocation>,
302 locations: &mut HashMap<String, ImportantLocation>,
303) {
304 if let Some(loc) = loc {
305 let key = location_key(loc);
306 if let Some(existing) = locations.get_mut(&key) {
307 existing.node_types.insert(node_type);
308 } else {
309 let mut node_types = HashSet::new();
310 node_types.insert(node_type);
311 locations.insert(
312 key.clone(),
313 ImportantLocation {
314 key,
315 loc: loc.clone(),
316 node_types,
317 },
318 );
319 }
320 }
321}
322
323fn collect_original_block(
324 stmts: &[Statement],
325 in_single_return_arrow: bool,
326 locations: &mut HashMap<String, ImportantLocation>,
327) {
328 for stmt in stmts {
329 collect_original_statement(stmt, in_single_return_arrow, locations);
330 }
331}
332
333fn collect_original_statement(
334 stmt: &Statement,
335 in_single_return_arrow: bool,
336 locations: &mut HashMap<String, ImportantLocation>,
337) {
338 if let Some(type_name) = important_statement_type(stmt) {
340 if type_name == "ReturnStatement" && in_single_return_arrow {
343 if let Statement::ReturnStatement(ret) = stmt {
344 if ret.argument.is_some() {
345 if let Some(arg) = &ret.argument {
347 collect_original_expression(arg, locations);
348 }
349 return;
350 }
351 }
352 }
353
354 if type_name == "ExpressionStatement" {
356 if let Statement::ExpressionStatement(expr_stmt) = stmt {
357 if is_manual_memoization(&expr_stmt.expression) {
358 collect_original_expression(&expr_stmt.expression, locations);
360 return;
361 }
362 }
363 }
364
365 let base_loc = statement_loc(stmt);
366 record_important(type_name, base_loc, locations);
367 }
368
369 match stmt {
371 Statement::BlockStatement(node) => {
372 collect_original_block(&node.body, false, locations);
373 }
374 Statement::ReturnStatement(node) => {
375 if let Some(arg) = &node.argument {
376 collect_original_expression(arg, locations);
377 }
378 }
379 Statement::ExpressionStatement(node) => {
380 collect_original_expression(&node.expression, locations);
381 }
382 Statement::IfStatement(node) => {
383 collect_original_expression(&node.test, locations);
384 collect_original_statement(&node.consequent, false, locations);
385 if let Some(alt) = &node.alternate {
386 collect_original_statement(alt, false, locations);
387 }
388 }
389 Statement::ForStatement(node) => {
390 if let Some(init) = &node.init {
391 match init.as_ref() {
392 ForInit::VariableDeclaration(decl) => {
393 collect_original_var_declaration(decl, locations);
394 }
395 ForInit::Expression(expr) => {
396 collect_original_expression(expr, locations);
397 }
398 }
399 }
400 if let Some(test) = &node.test {
401 collect_original_expression(test, locations);
402 }
403 if let Some(update) = &node.update {
404 collect_original_expression(update, locations);
405 }
406 collect_original_statement(&node.body, false, locations);
407 }
408 Statement::WhileStatement(node) => {
409 collect_original_expression(&node.test, locations);
410 collect_original_statement(&node.body, false, locations);
411 }
412 Statement::DoWhileStatement(node) => {
413 collect_original_statement(&node.body, false, locations);
414 collect_original_expression(&node.test, locations);
415 }
416 Statement::ForInStatement(node) => {
417 if let ForInOfLeft::Pattern(pat) = node.left.as_ref() {
418 collect_original_pattern(pat, locations);
419 }
420 collect_original_expression(&node.right, locations);
421 collect_original_statement(&node.body, false, locations);
422 }
423 Statement::ForOfStatement(node) => {
424 if let ForInOfLeft::Pattern(pat) = node.left.as_ref() {
425 collect_original_pattern(pat, locations);
426 }
427 collect_original_expression(&node.right, locations);
428 collect_original_statement(&node.body, false, locations);
429 }
430 Statement::SwitchStatement(node) => {
431 collect_original_expression(&node.discriminant, locations);
432 for case in &node.cases {
433 record_important("SwitchCase", &case.base.loc, locations);
435 if let Some(test) = &case.test {
436 collect_original_expression(test, locations);
437 }
438 collect_original_block(&case.consequent, false, locations);
439 }
440 }
441 Statement::ThrowStatement(node) => {
442 collect_original_expression(&node.argument, locations);
443 }
444 Statement::TryStatement(node) => {
445 collect_original_block(&node.block.body, false, locations);
446 if let Some(handler) = &node.handler {
447 if let Some(param) = &handler.param {
448 collect_original_pattern(param, locations);
449 }
450 collect_original_block(&handler.body.body, false, locations);
451 }
452 if let Some(finalizer) = &node.finalizer {
453 collect_original_block(&finalizer.body, false, locations);
454 }
455 }
456 Statement::LabeledStatement(node) => {
457 record_important("Identifier", &node.label.base.loc, locations);
459 collect_original_statement(&node.body, false, locations);
460 }
461 Statement::VariableDeclaration(node) => {
462 collect_original_var_declaration(node, locations);
463 }
464 Statement::FunctionDeclaration(node) => {
465 if let Some(id) = &node.id {
466 record_important("Identifier", &id.base.loc, locations);
467 }
468 for param in &node.params {
469 collect_original_pattern(param, locations);
470 }
471 collect_original_block(&node.body.body, false, locations);
472 }
473 Statement::WithStatement(node) => {
474 collect_original_expression(&node.object, locations);
475 collect_original_statement(&node.body, false, locations);
476 }
477 _ => {}
479 }
480}
481
482fn collect_original_var_declaration(
483 decl: &VariableDeclaration,
484 locations: &mut HashMap<String, ImportantLocation>,
485) {
486 for declarator in &decl.declarations {
487 record_important("VariableDeclarator", &declarator.base.loc, locations);
489 collect_original_pattern(&declarator.id, locations);
490 if let Some(init) = &declarator.init {
491 collect_original_expression(init, locations);
492 }
493 }
494}
495
496fn collect_original_expression(
497 expr: &Expression,
498 locations: &mut HashMap<String, ImportantLocation>,
499) {
500 if let Some(type_name) = important_expression_type(expr) {
502 if !is_manual_memoization(expr) {
504 let base_loc = expression_loc(expr);
505 record_important(type_name, base_loc, locations);
506 }
507 }
508
509 match expr {
511 Expression::Identifier(_) => {
512 }
514 Expression::CallExpression(node) => {
515 collect_original_expression(&node.callee, locations);
516 for arg in &node.arguments {
517 collect_original_expression(arg, locations);
518 }
519 }
520 Expression::MemberExpression(node) => {
521 collect_original_expression(&node.object, locations);
522 if node.computed {
523 collect_original_expression(&node.property, locations);
524 } else {
525 if let Expression::Identifier(id) = node.property.as_ref() {
527 record_important("Identifier", &id.base.loc, locations);
528 }
529 }
530 }
531 Expression::OptionalCallExpression(node) => {
532 collect_original_expression(&node.callee, locations);
533 for arg in &node.arguments {
534 collect_original_expression(arg, locations);
535 }
536 }
537 Expression::OptionalMemberExpression(node) => {
538 collect_original_expression(&node.object, locations);
539 if node.computed {
540 collect_original_expression(&node.property, locations);
541 } else if let Expression::Identifier(id) = node.property.as_ref() {
542 record_important("Identifier", &id.base.loc, locations);
543 }
544 }
545 Expression::BinaryExpression(node) => {
546 collect_original_expression(&node.left, locations);
547 collect_original_expression(&node.right, locations);
548 }
549 Expression::LogicalExpression(node) => {
550 collect_original_expression(&node.left, locations);
551 collect_original_expression(&node.right, locations);
552 }
553 Expression::UnaryExpression(node) => {
554 collect_original_expression(&node.argument, locations);
555 }
556 Expression::UpdateExpression(node) => {
557 collect_original_expression(&node.argument, locations);
558 }
559 Expression::ConditionalExpression(node) => {
560 collect_original_expression(&node.test, locations);
561 collect_original_expression(&node.consequent, locations);
562 collect_original_expression(&node.alternate, locations);
563 }
564 Expression::AssignmentExpression(node) => {
565 collect_original_pattern(&node.left, locations);
566 collect_original_expression(&node.right, locations);
567 }
568 Expression::SequenceExpression(node) => {
569 for e in &node.expressions {
570 collect_original_expression(e, locations);
571 }
572 }
573 Expression::ArrowFunctionExpression(node) => {
574 collect_original_arrow_children(node, locations);
575 }
576 Expression::FunctionExpression(node) => {
577 collect_original_fn_expr_children(node, locations);
578 }
579 Expression::ObjectExpression(node) => {
580 for prop in &node.properties {
581 match prop {
582 ObjectExpressionProperty::ObjectProperty(p) => {
583 if p.computed {
584 collect_original_expression(&p.key, locations);
585 } else if let Expression::Identifier(id) = p.key.as_ref() {
586 record_important("Identifier", &id.base.loc, locations);
587 }
588 collect_original_expression(&p.value, locations);
589 }
590 ObjectExpressionProperty::ObjectMethod(m) => {
591 record_important("ObjectMethod", &m.base.loc, locations);
593 for param in &m.params {
594 collect_original_pattern(param, locations);
595 }
596 collect_original_block(&m.body.body, false, locations);
597 }
598 ObjectExpressionProperty::SpreadElement(s) => {
599 collect_original_expression(&s.argument, locations);
600 }
601 }
602 }
603 }
604 Expression::ArrayExpression(node) => {
605 for elem in node.elements.iter().flatten() {
606 collect_original_expression(elem, locations);
607 }
608 }
609 Expression::NewExpression(node) => {
610 collect_original_expression(&node.callee, locations);
611 for arg in &node.arguments {
612 collect_original_expression(arg, locations);
613 }
614 }
615 Expression::TemplateLiteral(node) => {
616 for e in &node.expressions {
617 collect_original_expression(e, locations);
618 }
619 }
620 Expression::TaggedTemplateExpression(node) => {
621 collect_original_expression(&node.tag, locations);
622 for e in &node.quasi.expressions {
623 collect_original_expression(e, locations);
624 }
625 }
626 Expression::AwaitExpression(node) => {
627 collect_original_expression(&node.argument, locations);
628 }
629 Expression::YieldExpression(node) => {
630 if let Some(arg) = &node.argument {
631 collect_original_expression(arg, locations);
632 }
633 }
634 Expression::SpreadElement(node) => {
635 collect_original_expression(&node.argument, locations);
636 }
637 Expression::ParenthesizedExpression(node) => {
638 collect_original_expression(&node.expression, locations);
639 }
640 Expression::AssignmentPattern(node) => {
641 collect_original_pattern(&node.left, locations);
642 collect_original_expression(&node.right, locations);
643 }
644 Expression::ClassExpression(node) => {
645 if let Some(sc) = &node.super_class {
646 collect_original_expression(sc, locations);
647 }
648 }
649 Expression::TSAsExpression(node) => {
651 collect_original_expression(&node.expression, locations);
652 }
653 Expression::TSSatisfiesExpression(node) => {
654 collect_original_expression(&node.expression, locations);
655 }
656 Expression::TSNonNullExpression(node) => {
657 collect_original_expression(&node.expression, locations);
658 }
659 Expression::TSTypeAssertion(node) => {
660 collect_original_expression(&node.expression, locations);
661 }
662 Expression::TSInstantiationExpression(node) => {
663 collect_original_expression(&node.expression, locations);
664 }
665 Expression::TypeCastExpression(node) => {
666 collect_original_expression(&node.expression, locations);
667 }
668 _ => {}
670 }
671}
672
673fn collect_original_arrow_children(
674 arrow: &ArrowFunctionExpression,
675 locations: &mut HashMap<String, ImportantLocation>,
676) {
677 for param in &arrow.params {
678 collect_original_pattern(param, locations);
679 }
680 match arrow.body.as_ref() {
681 ArrowFunctionBody::BlockStatement(block) => {
682 let is_single_return =
683 block.body.len() == 1 && block.directives.is_empty();
684 collect_original_block(&block.body, is_single_return, locations);
685 }
686 ArrowFunctionBody::Expression(expr) => {
687 collect_original_expression(expr, locations);
688 }
689 }
690}
691
692fn collect_original_fn_expr_children(
693 func: &FunctionExpression,
694 locations: &mut HashMap<String, ImportantLocation>,
695) {
696 if let Some(id) = &func.id {
697 record_important("Identifier", &id.base.loc, locations);
698 }
699 for param in &func.params {
700 collect_original_pattern(param, locations);
701 }
702 collect_original_block(&func.body.body, false, locations);
703}
704
705fn collect_original_pattern(
706 pattern: &PatternLike,
707 locations: &mut HashMap<String, ImportantLocation>,
708) {
709 match pattern {
710 PatternLike::Identifier(id) => {
711 record_important("Identifier", &id.base.loc, locations);
712 }
713 PatternLike::AssignmentPattern(ap) => {
714 record_important("AssignmentPattern", &ap.base.loc, locations);
715 collect_original_pattern(&ap.left, locations);
716 collect_original_expression(&ap.right, locations);
717 }
718 PatternLike::ObjectPattern(op) => {
719 for prop in &op.properties {
720 match prop {
721 react_compiler_ast::patterns::ObjectPatternProperty::ObjectProperty(p) => {
722 if p.computed {
723 collect_original_expression(&p.key, locations);
724 } else if let Expression::Identifier(id) = p.key.as_ref() {
725 record_important("Identifier", &id.base.loc, locations);
726 }
727 collect_original_pattern(&p.value, locations);
728 }
729 react_compiler_ast::patterns::ObjectPatternProperty::RestElement(r) => {
730 collect_original_pattern(&r.argument, locations);
731 }
732 }
733 }
734 }
735 PatternLike::ArrayPattern(ap) => {
736 for elem in ap.elements.iter().flatten() {
737 collect_original_pattern(elem, locations);
738 }
739 }
740 PatternLike::RestElement(r) => {
741 collect_original_pattern(&r.argument, locations);
742 }
743 PatternLike::MemberExpression(m) => {
744 collect_original_expression(
745 &Expression::MemberExpression(m.clone()),
746 locations,
747 );
748 }
749 PatternLike::TSAsExpression(_)
750 | PatternLike::TSSatisfiesExpression(_)
751 | PatternLike::TSNonNullExpression(_)
752 | PatternLike::TSTypeAssertion(_)
753 | PatternLike::TypeCastExpression(_) => {}
754 }
755}
756
757fn statement_loc(stmt: &Statement) -> &Option<AstSourceLocation> {
760 match stmt {
761 Statement::BlockStatement(n) => &n.base.loc,
762 Statement::ReturnStatement(n) => &n.base.loc,
763 Statement::IfStatement(n) => &n.base.loc,
764 Statement::ForStatement(n) => &n.base.loc,
765 Statement::WhileStatement(n) => &n.base.loc,
766 Statement::DoWhileStatement(n) => &n.base.loc,
767 Statement::ForInStatement(n) => &n.base.loc,
768 Statement::ForOfStatement(n) => &n.base.loc,
769 Statement::SwitchStatement(n) => &n.base.loc,
770 Statement::ThrowStatement(n) => &n.base.loc,
771 Statement::TryStatement(n) => &n.base.loc,
772 Statement::BreakStatement(n) => &n.base.loc,
773 Statement::ContinueStatement(n) => &n.base.loc,
774 Statement::LabeledStatement(n) => &n.base.loc,
775 Statement::ExpressionStatement(n) => &n.base.loc,
776 Statement::EmptyStatement(n) => &n.base.loc,
777 Statement::DebuggerStatement(n) => &n.base.loc,
778 Statement::WithStatement(n) => &n.base.loc,
779 Statement::VariableDeclaration(n) => &n.base.loc,
780 Statement::FunctionDeclaration(n) => &n.base.loc,
781 Statement::ClassDeclaration(n) => &n.base.loc,
782 Statement::ImportDeclaration(n) => &n.base.loc,
783 Statement::ExportNamedDeclaration(n) => &n.base.loc,
784 Statement::ExportDefaultDeclaration(n) => &n.base.loc,
785 Statement::ExportAllDeclaration(n) => &n.base.loc,
786 Statement::TSTypeAliasDeclaration(n) => &n.base.loc,
787 Statement::TSInterfaceDeclaration(n) => &n.base.loc,
788 Statement::TSEnumDeclaration(n) => &n.base.loc,
789 Statement::TSModuleDeclaration(n) => &n.base.loc,
790 Statement::TSDeclareFunction(n) => &n.base.loc,
791 Statement::TypeAlias(n) => &n.base.loc,
792 Statement::OpaqueType(n) => &n.base.loc,
793 Statement::InterfaceDeclaration(n) => &n.base.loc,
794 Statement::DeclareVariable(n) => &n.base.loc,
795 Statement::DeclareFunction(n) => &n.base.loc,
796 Statement::DeclareClass(n) => &n.base.loc,
797 Statement::DeclareModule(n) => &n.base.loc,
798 Statement::DeclareModuleExports(n) => &n.base.loc,
799 Statement::DeclareExportDeclaration(n) => &n.base.loc,
800 Statement::DeclareExportAllDeclaration(n) => &n.base.loc,
801 Statement::DeclareInterface(n) => &n.base.loc,
802 Statement::DeclareTypeAlias(n) => &n.base.loc,
803 Statement::DeclareOpaqueType(n) => &n.base.loc,
804 Statement::EnumDeclaration(n) => &n.base.loc,
805 Statement::Unknown(n) => &n.base().loc,
806 }
807}
808
809fn expression_loc(expr: &Expression) -> &Option<AstSourceLocation> {
810 match expr {
811 Expression::Identifier(n) => &n.base.loc,
812 Expression::StringLiteral(n) => &n.base.loc,
813 Expression::NumericLiteral(n) => &n.base.loc,
814 Expression::BooleanLiteral(n) => &n.base.loc,
815 Expression::NullLiteral(n) => &n.base.loc,
816 Expression::BigIntLiteral(n) => &n.base.loc,
817 Expression::RegExpLiteral(n) => &n.base.loc,
818 Expression::CallExpression(n) => &n.base.loc,
819 Expression::MemberExpression(n) => &n.base.loc,
820 Expression::OptionalCallExpression(n) => &n.base.loc,
821 Expression::OptionalMemberExpression(n) => &n.base.loc,
822 Expression::BinaryExpression(n) => &n.base.loc,
823 Expression::LogicalExpression(n) => &n.base.loc,
824 Expression::UnaryExpression(n) => &n.base.loc,
825 Expression::UpdateExpression(n) => &n.base.loc,
826 Expression::ConditionalExpression(n) => &n.base.loc,
827 Expression::AssignmentExpression(n) => &n.base.loc,
828 Expression::SequenceExpression(n) => &n.base.loc,
829 Expression::ArrowFunctionExpression(n) => &n.base.loc,
830 Expression::FunctionExpression(n) => &n.base.loc,
831 Expression::ObjectExpression(n) => &n.base.loc,
832 Expression::ArrayExpression(n) => &n.base.loc,
833 Expression::NewExpression(n) => &n.base.loc,
834 Expression::TemplateLiteral(n) => &n.base.loc,
835 Expression::TaggedTemplateExpression(n) => &n.base.loc,
836 Expression::AwaitExpression(n) => &n.base.loc,
837 Expression::YieldExpression(n) => &n.base.loc,
838 Expression::SpreadElement(n) => &n.base.loc,
839 Expression::MetaProperty(n) => &n.base.loc,
840 Expression::ClassExpression(n) => &n.base.loc,
841 Expression::PrivateName(n) => &n.base.loc,
842 Expression::Super(n) => &n.base.loc,
843 Expression::Import(n) => &n.base.loc,
844 Expression::ThisExpression(n) => &n.base.loc,
845 Expression::ParenthesizedExpression(n) => &n.base.loc,
846 Expression::AssignmentPattern(n) => &n.base.loc,
847 Expression::JSXElement(n) => &n.base.loc,
848 Expression::JSXFragment(n) => &n.base.loc,
849 Expression::TSAsExpression(n) => &n.base.loc,
850 Expression::TSSatisfiesExpression(n) => &n.base.loc,
851 Expression::TSNonNullExpression(n) => &n.base.loc,
852 Expression::TSTypeAssertion(n) => &n.base.loc,
853 Expression::TSInstantiationExpression(n) => &n.base.loc,
854 Expression::TypeCastExpression(n) => &n.base.loc,
855 }
856}
857
858fn collect_generated_from_block(
863 stmts: &[Statement],
864 locations: &mut HashMap<String, HashSet<String>>,
865) {
866 for stmt in stmts {
867 collect_generated_statement(stmt, locations);
868 }
869}
870
871fn record_generated(
872 type_name: &str,
873 loc: &Option<AstSourceLocation>,
874 locations: &mut HashMap<String, HashSet<String>>,
875) {
876 if let Some(loc) = loc {
877 let key = location_key(loc);
878 locations
879 .entry(key)
880 .or_default()
881 .insert(type_name.to_string());
882 }
883}
884
885fn collect_generated_statement(
886 stmt: &Statement,
887 locations: &mut HashMap<String, HashSet<String>>,
888) {
889 let type_name = statement_type_name(stmt);
891 record_generated(type_name, statement_loc(stmt), locations);
892
893 match stmt {
895 Statement::BlockStatement(node) => {
896 collect_generated_from_block(&node.body, locations);
897 }
898 Statement::ReturnStatement(node) => {
899 if let Some(arg) = &node.argument {
900 collect_generated_expression(arg, locations);
901 }
902 }
903 Statement::ExpressionStatement(node) => {
904 collect_generated_expression(&node.expression, locations);
905 }
906 Statement::IfStatement(node) => {
907 collect_generated_expression(&node.test, locations);
908 collect_generated_statement(&node.consequent, locations);
909 if let Some(alt) = &node.alternate {
910 collect_generated_statement(alt, locations);
911 }
912 }
913 Statement::ForStatement(node) => {
914 if let Some(init) = &node.init {
915 match init.as_ref() {
916 ForInit::VariableDeclaration(decl) => {
917 collect_generated_var_declaration(decl, locations);
918 }
919 ForInit::Expression(expr) => {
920 collect_generated_expression(expr, locations);
921 }
922 }
923 }
924 if let Some(test) = &node.test {
925 collect_generated_expression(test, locations);
926 }
927 if let Some(update) = &node.update {
928 collect_generated_expression(update, locations);
929 }
930 collect_generated_statement(&node.body, locations);
931 }
932 Statement::WhileStatement(node) => {
933 collect_generated_expression(&node.test, locations);
934 collect_generated_statement(&node.body, locations);
935 }
936 Statement::DoWhileStatement(node) => {
937 collect_generated_statement(&node.body, locations);
938 collect_generated_expression(&node.test, locations);
939 }
940 Statement::ForInStatement(node) => {
941 match node.left.as_ref() {
942 ForInOfLeft::VariableDeclaration(decl) => {
943 collect_generated_var_declaration(decl, locations);
944 }
945 ForInOfLeft::Pattern(pat) => {
946 collect_generated_pattern(pat, locations);
947 }
948 }
949 collect_generated_expression(&node.right, locations);
950 collect_generated_statement(&node.body, locations);
951 }
952 Statement::ForOfStatement(node) => {
953 match node.left.as_ref() {
954 ForInOfLeft::VariableDeclaration(decl) => {
955 collect_generated_var_declaration(decl, locations);
956 }
957 ForInOfLeft::Pattern(pat) => {
958 collect_generated_pattern(pat, locations);
959 }
960 }
961 collect_generated_expression(&node.right, locations);
962 collect_generated_statement(&node.body, locations);
963 }
964 Statement::SwitchStatement(node) => {
965 collect_generated_expression(&node.discriminant, locations);
966 for case in &node.cases {
967 record_generated("SwitchCase", &case.base.loc, locations);
968 if let Some(test) = &case.test {
969 collect_generated_expression(test, locations);
970 }
971 collect_generated_from_block(&case.consequent, locations);
972 }
973 }
974 Statement::ThrowStatement(node) => {
975 collect_generated_expression(&node.argument, locations);
976 }
977 Statement::TryStatement(node) => {
978 collect_generated_from_block(&node.block.body, locations);
979 if let Some(handler) = &node.handler {
980 if let Some(param) = &handler.param {
981 collect_generated_pattern(param, locations);
982 }
983 collect_generated_from_block(&handler.body.body, locations);
984 }
985 if let Some(finalizer) = &node.finalizer {
986 collect_generated_from_block(&finalizer.body, locations);
987 }
988 }
989 Statement::LabeledStatement(node) => {
990 record_generated("Identifier", &node.label.base.loc, locations);
991 collect_generated_statement(&node.body, locations);
992 }
993 Statement::VariableDeclaration(node) => {
994 collect_generated_var_declaration(node, locations);
995 }
996 Statement::FunctionDeclaration(node) => {
997 if let Some(id) = &node.id {
998 record_generated("Identifier", &id.base.loc, locations);
999 }
1000 for param in &node.params {
1001 collect_generated_pattern(param, locations);
1002 }
1003 collect_generated_from_block(&node.body.body, locations);
1004 }
1005 Statement::WithStatement(node) => {
1006 collect_generated_expression(&node.object, locations);
1007 collect_generated_statement(&node.body, locations);
1008 }
1009 Statement::ClassDeclaration(node) => {
1010 if let Some(id) = &node.id {
1011 record_generated("Identifier", &id.base.loc, locations);
1012 }
1013 if let Some(sc) = &node.super_class {
1014 collect_generated_expression(sc, locations);
1015 }
1016 }
1017 _ => {}
1018 }
1019}
1020
1021fn collect_generated_var_declaration(
1022 decl: &VariableDeclaration,
1023 locations: &mut HashMap<String, HashSet<String>>,
1024) {
1025 for declarator in &decl.declarations {
1026 record_generated("VariableDeclarator", &declarator.base.loc, locations);
1027 collect_generated_pattern(&declarator.id, locations);
1028 if let Some(init) = &declarator.init {
1029 collect_generated_expression(init, locations);
1030 }
1031 }
1032}
1033
1034fn collect_generated_expression(
1035 expr: &Expression,
1036 locations: &mut HashMap<String, HashSet<String>>,
1037) {
1038 let type_name = expression_type_name(expr);
1039 record_generated(type_name, expression_loc(expr), locations);
1040
1041 match expr {
1042 Expression::Identifier(_) => {}
1043 Expression::CallExpression(node) => {
1044 collect_generated_expression(&node.callee, locations);
1045 for arg in &node.arguments {
1046 collect_generated_expression(arg, locations);
1047 }
1048 }
1049 Expression::MemberExpression(node) => {
1050 collect_generated_expression(&node.object, locations);
1051 collect_generated_expression(&node.property, locations);
1052 }
1053 Expression::OptionalCallExpression(node) => {
1054 collect_generated_expression(&node.callee, locations);
1055 for arg in &node.arguments {
1056 collect_generated_expression(arg, locations);
1057 }
1058 }
1059 Expression::OptionalMemberExpression(node) => {
1060 collect_generated_expression(&node.object, locations);
1061 collect_generated_expression(&node.property, locations);
1062 }
1063 Expression::BinaryExpression(node) => {
1064 collect_generated_expression(&node.left, locations);
1065 collect_generated_expression(&node.right, locations);
1066 }
1067 Expression::LogicalExpression(node) => {
1068 collect_generated_expression(&node.left, locations);
1069 collect_generated_expression(&node.right, locations);
1070 }
1071 Expression::UnaryExpression(node) => {
1072 collect_generated_expression(&node.argument, locations);
1073 }
1074 Expression::UpdateExpression(node) => {
1075 collect_generated_expression(&node.argument, locations);
1076 }
1077 Expression::ConditionalExpression(node) => {
1078 collect_generated_expression(&node.test, locations);
1079 collect_generated_expression(&node.consequent, locations);
1080 collect_generated_expression(&node.alternate, locations);
1081 }
1082 Expression::AssignmentExpression(node) => {
1083 collect_generated_pattern(&node.left, locations);
1084 collect_generated_expression(&node.right, locations);
1085 }
1086 Expression::SequenceExpression(node) => {
1087 for e in &node.expressions {
1088 collect_generated_expression(e, locations);
1089 }
1090 }
1091 Expression::ArrowFunctionExpression(node) => {
1092 for param in &node.params {
1093 collect_generated_pattern(param, locations);
1094 }
1095 match node.body.as_ref() {
1096 ArrowFunctionBody::BlockStatement(block) => {
1097 collect_generated_from_block(&block.body, locations);
1098 }
1099 ArrowFunctionBody::Expression(e) => {
1100 collect_generated_expression(e, locations);
1101 }
1102 }
1103 }
1104 Expression::FunctionExpression(node) => {
1105 if let Some(id) = &node.id {
1106 record_generated("Identifier", &id.base.loc, locations);
1107 }
1108 for param in &node.params {
1109 collect_generated_pattern(param, locations);
1110 }
1111 collect_generated_from_block(&node.body.body, locations);
1112 }
1113 Expression::ObjectExpression(node) => {
1114 for prop in &node.properties {
1115 match prop {
1116 ObjectExpressionProperty::ObjectProperty(p) => {
1117 collect_generated_expression(&p.key, locations);
1118 collect_generated_expression(&p.value, locations);
1119 }
1120 ObjectExpressionProperty::ObjectMethod(m) => {
1121 record_generated("ObjectMethod", &m.base.loc, locations);
1122 for param in &m.params {
1123 collect_generated_pattern(param, locations);
1124 }
1125 collect_generated_from_block(&m.body.body, locations);
1126 }
1127 ObjectExpressionProperty::SpreadElement(s) => {
1128 collect_generated_expression(&s.argument, locations);
1129 }
1130 }
1131 }
1132 }
1133 Expression::ArrayExpression(node) => {
1134 for elem in node.elements.iter().flatten() {
1135 collect_generated_expression(elem, locations);
1136 }
1137 }
1138 Expression::NewExpression(node) => {
1139 collect_generated_expression(&node.callee, locations);
1140 for arg in &node.arguments {
1141 collect_generated_expression(arg, locations);
1142 }
1143 }
1144 Expression::TemplateLiteral(node) => {
1145 for e in &node.expressions {
1146 collect_generated_expression(e, locations);
1147 }
1148 }
1149 Expression::TaggedTemplateExpression(node) => {
1150 collect_generated_expression(&node.tag, locations);
1151 for e in &node.quasi.expressions {
1152 collect_generated_expression(e, locations);
1153 }
1154 }
1155 Expression::AwaitExpression(node) => {
1156 collect_generated_expression(&node.argument, locations);
1157 }
1158 Expression::YieldExpression(node) => {
1159 if let Some(arg) = &node.argument {
1160 collect_generated_expression(arg, locations);
1161 }
1162 }
1163 Expression::SpreadElement(node) => {
1164 collect_generated_expression(&node.argument, locations);
1165 }
1166 Expression::ParenthesizedExpression(node) => {
1167 collect_generated_expression(&node.expression, locations);
1168 }
1169 Expression::AssignmentPattern(node) => {
1170 collect_generated_pattern(&node.left, locations);
1171 collect_generated_expression(&node.right, locations);
1172 }
1173 Expression::ClassExpression(node) => {
1174 if let Some(sc) = &node.super_class {
1175 collect_generated_expression(sc, locations);
1176 }
1177 }
1178 Expression::TSAsExpression(node) => {
1179 collect_generated_expression(&node.expression, locations);
1180 }
1181 Expression::TSSatisfiesExpression(node) => {
1182 collect_generated_expression(&node.expression, locations);
1183 }
1184 Expression::TSNonNullExpression(node) => {
1185 collect_generated_expression(&node.expression, locations);
1186 }
1187 Expression::TSTypeAssertion(node) => {
1188 collect_generated_expression(&node.expression, locations);
1189 }
1190 Expression::TSInstantiationExpression(node) => {
1191 collect_generated_expression(&node.expression, locations);
1192 }
1193 Expression::TypeCastExpression(node) => {
1194 collect_generated_expression(&node.expression, locations);
1195 }
1196 _ => {}
1198 }
1199}
1200
1201fn collect_generated_pattern(
1202 pattern: &PatternLike,
1203 locations: &mut HashMap<String, HashSet<String>>,
1204) {
1205 match pattern {
1206 PatternLike::Identifier(id) => {
1207 record_generated("Identifier", &id.base.loc, locations);
1208 }
1209 PatternLike::AssignmentPattern(ap) => {
1210 record_generated("AssignmentPattern", &ap.base.loc, locations);
1211 collect_generated_pattern(&ap.left, locations);
1212 collect_generated_expression(&ap.right, locations);
1213 }
1214 PatternLike::ObjectPattern(op) => {
1215 record_generated("ObjectPattern", &op.base.loc, locations);
1216 for prop in &op.properties {
1217 match prop {
1218 react_compiler_ast::patterns::ObjectPatternProperty::ObjectProperty(p) => {
1219 record_generated("ObjectProperty", &p.base.loc, locations);
1220 collect_generated_expression(&p.key, locations);
1221 collect_generated_pattern(&p.value, locations);
1222 }
1223 react_compiler_ast::patterns::ObjectPatternProperty::RestElement(r) => {
1224 record_generated("RestElement", &r.base.loc, locations);
1225 collect_generated_pattern(&r.argument, locations);
1226 }
1227 }
1228 }
1229 }
1230 PatternLike::ArrayPattern(ap) => {
1231 record_generated("ArrayPattern", &ap.base.loc, locations);
1232 for elem in ap.elements.iter().flatten() {
1233 collect_generated_pattern(elem, locations);
1234 }
1235 }
1236 PatternLike::RestElement(r) => {
1237 record_generated("RestElement", &r.base.loc, locations);
1238 collect_generated_pattern(&r.argument, locations);
1239 }
1240 PatternLike::MemberExpression(m) => {
1241 record_generated("MemberExpression", &m.base.loc, locations);
1242 collect_generated_expression(&m.object, locations);
1243 collect_generated_expression(&m.property, locations);
1244 }
1245 PatternLike::TSAsExpression(_)
1246 | PatternLike::TSSatisfiesExpression(_)
1247 | PatternLike::TSNonNullExpression(_)
1248 | PatternLike::TSTypeAssertion(_)
1249 | PatternLike::TypeCastExpression(_) => {}
1250 }
1251}
1252
1253fn statement_type_name(stmt: &Statement) -> &'static str {
1256 match stmt {
1257 Statement::BlockStatement(_) => "BlockStatement",
1258 Statement::ReturnStatement(_) => "ReturnStatement",
1259 Statement::IfStatement(_) => "IfStatement",
1260 Statement::ForStatement(_) => "ForStatement",
1261 Statement::WhileStatement(_) => "WhileStatement",
1262 Statement::DoWhileStatement(_) => "DoWhileStatement",
1263 Statement::ForInStatement(_) => "ForInStatement",
1264 Statement::ForOfStatement(_) => "ForOfStatement",
1265 Statement::SwitchStatement(_) => "SwitchStatement",
1266 Statement::ThrowStatement(_) => "ThrowStatement",
1267 Statement::TryStatement(_) => "TryStatement",
1268 Statement::BreakStatement(_) => "BreakStatement",
1269 Statement::ContinueStatement(_) => "ContinueStatement",
1270 Statement::LabeledStatement(_) => "LabeledStatement",
1271 Statement::ExpressionStatement(_) => "ExpressionStatement",
1272 Statement::EmptyStatement(_) => "EmptyStatement",
1273 Statement::DebuggerStatement(_) => "DebuggerStatement",
1274 Statement::WithStatement(_) => "WithStatement",
1275 Statement::VariableDeclaration(_) => "VariableDeclaration",
1276 Statement::FunctionDeclaration(_) => "FunctionDeclaration",
1277 Statement::ClassDeclaration(_) => "ClassDeclaration",
1278 Statement::ImportDeclaration(_) => "ImportDeclaration",
1279 Statement::ExportNamedDeclaration(_) => "ExportNamedDeclaration",
1280 Statement::ExportDefaultDeclaration(_) => "ExportDefaultDeclaration",
1281 Statement::ExportAllDeclaration(_) => "ExportAllDeclaration",
1282 Statement::TSTypeAliasDeclaration(_) => "TSTypeAliasDeclaration",
1283 Statement::TSInterfaceDeclaration(_) => "TSInterfaceDeclaration",
1284 Statement::TSEnumDeclaration(_) => "TSEnumDeclaration",
1285 Statement::TSModuleDeclaration(_) => "TSModuleDeclaration",
1286 Statement::TSDeclareFunction(_) => "TSDeclareFunction",
1287 Statement::TypeAlias(_) => "TypeAlias",
1288 Statement::OpaqueType(_) => "OpaqueType",
1289 Statement::InterfaceDeclaration(_) => "InterfaceDeclaration",
1290 Statement::DeclareVariable(_) => "DeclareVariable",
1291 Statement::DeclareFunction(_) => "DeclareFunction",
1292 Statement::DeclareClass(_) => "DeclareClass",
1293 Statement::DeclareModule(_) => "DeclareModule",
1294 Statement::DeclareModuleExports(_) => "DeclareModuleExports",
1295 Statement::DeclareExportDeclaration(_) => "DeclareExportDeclaration",
1296 Statement::DeclareExportAllDeclaration(_) => "DeclareExportAllDeclaration",
1297 Statement::DeclareInterface(_) => "DeclareInterface",
1298 Statement::DeclareTypeAlias(_) => "DeclareTypeAlias",
1299 Statement::DeclareOpaqueType(_) => "DeclareOpaqueType",
1300 Statement::EnumDeclaration(_) => "EnumDeclaration",
1301 Statement::Unknown(_) => "Unknown",
1304 }
1305}
1306
1307fn expression_type_name(expr: &Expression) -> &'static str {
1308 match expr {
1309 Expression::Identifier(_) => "Identifier",
1310 Expression::StringLiteral(_) => "StringLiteral",
1311 Expression::NumericLiteral(_) => "NumericLiteral",
1312 Expression::BooleanLiteral(_) => "BooleanLiteral",
1313 Expression::NullLiteral(_) => "NullLiteral",
1314 Expression::BigIntLiteral(_) => "BigIntLiteral",
1315 Expression::RegExpLiteral(_) => "RegExpLiteral",
1316 Expression::CallExpression(_) => "CallExpression",
1317 Expression::MemberExpression(_) => "MemberExpression",
1318 Expression::OptionalCallExpression(_) => "OptionalCallExpression",
1319 Expression::OptionalMemberExpression(_) => "OptionalMemberExpression",
1320 Expression::BinaryExpression(_) => "BinaryExpression",
1321 Expression::LogicalExpression(_) => "LogicalExpression",
1322 Expression::UnaryExpression(_) => "UnaryExpression",
1323 Expression::UpdateExpression(_) => "UpdateExpression",
1324 Expression::ConditionalExpression(_) => "ConditionalExpression",
1325 Expression::AssignmentExpression(_) => "AssignmentExpression",
1326 Expression::SequenceExpression(_) => "SequenceExpression",
1327 Expression::ArrowFunctionExpression(_) => "ArrowFunctionExpression",
1328 Expression::FunctionExpression(_) => "FunctionExpression",
1329 Expression::ObjectExpression(_) => "ObjectExpression",
1330 Expression::ArrayExpression(_) => "ArrayExpression",
1331 Expression::NewExpression(_) => "NewExpression",
1332 Expression::TemplateLiteral(_) => "TemplateLiteral",
1333 Expression::TaggedTemplateExpression(_) => "TaggedTemplateExpression",
1334 Expression::AwaitExpression(_) => "AwaitExpression",
1335 Expression::YieldExpression(_) => "YieldExpression",
1336 Expression::SpreadElement(_) => "SpreadElement",
1337 Expression::MetaProperty(_) => "MetaProperty",
1338 Expression::ClassExpression(_) => "ClassExpression",
1339 Expression::PrivateName(_) => "PrivateName",
1340 Expression::Super(_) => "Super",
1341 Expression::Import(_) => "Import",
1342 Expression::ThisExpression(_) => "ThisExpression",
1343 Expression::ParenthesizedExpression(_) => "ParenthesizedExpression",
1344 Expression::AssignmentPattern(_) => "AssignmentPattern",
1345 Expression::JSXElement(_) => "JSXElement",
1346 Expression::JSXFragment(_) => "JSXFragment",
1347 Expression::TSAsExpression(_) => "TSAsExpression",
1348 Expression::TSSatisfiesExpression(_) => "TSSatisfiesExpression",
1349 Expression::TSNonNullExpression(_) => "TSNonNullExpression",
1350 Expression::TSTypeAssertion(_) => "TSTypeAssertion",
1351 Expression::TSInstantiationExpression(_) => "TSInstantiationExpression",
1352 Expression::TypeCastExpression(_) => "TypeCastExpression",
1353 }
1354}