main
rs 91 lines 2.85 KB
Raw
1 use react_compiler_ast::scope::ScopeInfo;
2 use react_compiler_ast::statements::FunctionDeclaration;
3 use react_compiler_hir::InstructionValue;
4 use react_compiler_hir::environment::Environment;
5 use react_compiler_lowering::{FunctionNode, lower};
6 use serde_json::json;
7
8 /// An unknown statement inside a function body degrades like the other
9 /// unsupported-statement arms: an UnsupportedSyntax error is recorded and an
10 /// UnsupportedNode instruction carries the raw node verbatim.
11 #[test]
12 fn unknown_statement_in_function_body_records_bailout() {
13 let unknown_node = json!({
14 "type": "TSFutureStatement",
15 "start": 40,
16 "end": 52,
17 "payload": { "type": "Identifier", "name": "x" }
18 });
19 let func: FunctionDeclaration = serde_json::from_value(json!({
20 "type": "FunctionDeclaration",
21 "start": 0,
22 "end": 60,
23 "id": { "type": "Identifier", "name": "useValue", "start": 9, "end": 17 },
24 "generator": false,
25 "async": false,
26 "params": [],
27 "body": {
28 "type": "BlockStatement",
29 "start": 20,
30 "end": 60,
31 "body": [unknown_node.clone()],
32 "directives": []
33 }
34 }))
35 .unwrap();
36
37 let scope_info: ScopeInfo = serde_json::from_value(json!({
38 "scopes": [
39 { "id": 0, "parent": null, "kind": "program", "bindings": { "useValue": 0 } },
40 { "id": 1, "parent": 0, "kind": "function", "bindings": {} }
41 ],
42 "bindings": [
43 {
44 "id": 0,
45 "name": "useValue",
46 "kind": "hoisted",
47 "scope": 0,
48 "declarationType": "FunctionDeclaration"
49 }
50 ],
51 "nodeToScope": { "0": 1 },
52 "referenceToBinding": {},
53 "programScope": 0
54 }))
55 .unwrap();
56
57 let mut env = Environment::new();
58 let result = lower(
59 &FunctionNode::FunctionDeclaration(&func),
60 None,
61 &scope_info,
62 &mut env,
63 );
64
65 assert!(
66 env.has_errors(),
67 "expected a recorded error, got result {result:?}"
68 );
69 let rendered = format!("{:?}", env.errors());
70 assert!(
71 rendered.contains("Unsupported statement kind 'TSFutureStatement'"),
72 "unexpected error payload: {rendered}"
73 );
74
75 let hir = result.expect("lowering degrades, it does not fail outright");
76 let unsupported = hir
77 .instructions
78 .iter()
79 .find_map(|instr| match &instr.value {
80 InstructionValue::UnsupportedNode {
81 node_type,
82 original_node,
83 ..
84 } => Some((node_type.clone(), original_node.clone())),
85 _ => None,
86 })
87 .expect("expected an UnsupportedNode instruction");
88
89 assert_eq!(unsupported.0.as_deref(), Some("TSFutureStatement"));
90 assert_eq!(unsupported.1, Some(unknown_node));
91 }