@vxrn/compiler 2.0.0-beta.33.1 → 2.0.0-beta.45.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/cjs/cache.cjs +112 -109
  2. package/dist/cjs/configure.cjs +26 -28
  3. package/dist/cjs/constants.cjs +56 -60
  4. package/dist/cjs/index.cjs +420 -438
  5. package/dist/cjs/reactNativeCodegen.cjs +105 -114
  6. package/dist/cjs/reactNativeViewConfig.cjs +362 -381
  7. package/dist/cjs/refresh-runtime.cjs +390 -397
  8. package/dist/cjs/transformBabel.cjs +278 -218
  9. package/dist/cjs/transformHermesAsync.cjs +36 -47
  10. package/dist/cjs/transformHermesLoops.cjs +279 -281
  11. package/dist/cjs/transformSWC.cjs +183 -200
  12. package/dist/cjs/transformWorklets.cjs +107 -95
  13. package/dist/cjs/types.cjs +9 -11
  14. package/dist/cjs/worklets/autoworklet.cjs +277 -222
  15. package/dist/cjs/worklets/globals.cjs +124 -60
  16. package/dist/cjs/worklets/hash.cjs +23 -27
  17. package/dist/cjs/worklets/scope.cjs +338 -359
  18. package/dist/cjs/worklets/serialize.cjs +73 -75
  19. package/dist/cjs/worklets/transform.cjs +217 -222
  20. package/dist/cjs/worklets/types.cjs +9 -11
  21. package/dist/esm/cache.mjs +96 -89
  22. package/dist/esm/cache.mjs.map +1 -1
  23. package/dist/esm/configure.mjs +11 -10
  24. package/dist/esm/configure.mjs.map +1 -1
  25. package/dist/esm/constants.mjs +41 -41
  26. package/dist/esm/constants.mjs.map +1 -1
  27. package/dist/esm/index.js +417 -420
  28. package/dist/esm/index.js.map +1 -1
  29. package/dist/esm/index.mjs +417 -420
  30. package/dist/esm/index.mjs.map +1 -1
  31. package/dist/esm/reactNativeCodegen.mjs +90 -88
  32. package/dist/esm/reactNativeCodegen.mjs.map +1 -1
  33. package/dist/esm/reactNativeViewConfig.mjs +347 -362
  34. package/dist/esm/reactNativeViewConfig.mjs.map +1 -1
  35. package/dist/esm/refresh-runtime.mjs +372 -376
  36. package/dist/esm/refresh-runtime.mjs.map +1 -1
  37. package/dist/esm/transformBabel.mjs +261 -194
  38. package/dist/esm/transformBabel.mjs.map +1 -1
  39. package/dist/esm/transformHermesAsync.mjs +20 -21
  40. package/dist/esm/transformHermesAsync.mjs.map +1 -1
  41. package/dist/esm/transformHermesLoops.mjs +264 -255
  42. package/dist/esm/transformHermesLoops.mjs.map +1 -1
  43. package/dist/esm/transformSWC.mjs +163 -171
  44. package/dist/esm/transformSWC.mjs.map +1 -1
  45. package/dist/esm/transformWorklets.mjs +89 -69
  46. package/dist/esm/transformWorklets.mjs.map +1 -1
  47. package/dist/esm/types.mjs +0 -2
  48. package/dist/esm/worklets/autoworklet.mjs +258 -200
  49. package/dist/esm/worklets/autoworklet.mjs.map +1 -1
  50. package/dist/esm/worklets/globals.mjs +109 -42
  51. package/dist/esm/worklets/globals.mjs.map +1 -1
  52. package/dist/esm/worklets/hash.mjs +10 -9
  53. package/dist/esm/worklets/hash.mjs.map +1 -1
  54. package/dist/esm/worklets/scope.mjs +325 -341
  55. package/dist/esm/worklets/scope.mjs.map +1 -1
  56. package/dist/esm/worklets/serialize.mjs +60 -58
  57. package/dist/esm/worklets/serialize.mjs.map +1 -1
  58. package/dist/esm/worklets/transform.mjs +201 -197
  59. package/dist/esm/worklets/transform.mjs.map +1 -1
  60. package/dist/esm/worklets/types.mjs +0 -2
  61. package/package.json +7 -6
  62. package/src/cache.ts +37 -7
  63. package/src/index.ts +33 -18
  64. package/src/transformBabel.test.ts +311 -1
  65. package/src/transformBabel.ts +110 -13
  66. package/types/cache.d.ts +2 -2
  67. package/types/cache.d.ts.map +1 -1
  68. package/types/index.d.ts.map +1 -1
  69. package/types/transformBabel.d.ts +16 -1
  70. package/types/transformBabel.d.ts.map +1 -1
  71. package/types/transformSWC.d.ts +1 -4
  72. package/types/transformSWC.d.ts.map +1 -1
  73. package/dist/cjs/transformBabel.test.cjs +0 -360
  74. package/dist/cjs/transformHermesLoops.test.cjs +0 -257
  75. package/dist/cjs/transformSWC.test.cjs +0 -117
  76. package/dist/cjs/transformWorklets.test.cjs +0 -604
  77. package/dist/esm/transformBabel.test.mjs +0 -337
  78. package/dist/esm/transformBabel.test.mjs.map +0 -1
  79. package/dist/esm/transformHermesLoops.test.mjs +0 -234
  80. package/dist/esm/transformHermesLoops.test.mjs.map +0 -1
  81. package/dist/esm/transformSWC.test.mjs +0 -118
  82. package/dist/esm/transformSWC.test.mjs.map +0 -1
  83. package/dist/esm/transformWorklets.test.mjs +0 -581
  84. package/dist/esm/transformWorklets.test.mjs.map +0 -1
  85. package/dist/esm/types.mjs.map +0 -1
  86. package/dist/esm/worklets/types.mjs.map +0 -1
  87. package/types/transformBabel.test.d.ts +0 -2
  88. package/types/transformBabel.test.d.ts.map +0 -1
  89. package/types/transformHermesLoops.test.d.ts +0 -2
  90. package/types/transformHermesLoops.test.d.ts.map +0 -1
  91. package/types/transformSWC.test.d.ts +0 -2
  92. package/types/transformSWC.test.d.ts.map +0 -1
  93. package/types/transformWorklets.test.d.ts +0 -2
  94. package/types/transformWorklets.test.d.ts.map +0 -1
@@ -5,315 +5,313 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __getProtoOf = Object.getPrototypeOf;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
7
  var __export = (target, all) => {
8
- for (var name in all) __defProp(target, name, {
9
- get: all[name],
10
- enumerable: true
11
- });
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
12
  };
13
13
  var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
- get: () => from[key],
17
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
- });
19
- }
20
- return to;
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
+ get: () => from[key],
17
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
+ });
19
+ }
20
+ return to;
21
21
  };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
- // If the importer is in node compatibility mode or this is not an ESM
24
- // file that has been converted to a CommonJS file using a Babel-
25
- // compatible transform (i.e. "__esModule" has not been set), then set
26
- // "default" to the CommonJS "module.exports" for node compatibility.
27
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
28
- value: mod,
29
- enumerable: true
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
30
25
  }) : target, mod));
31
- var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
32
- value: true
33
- }), mod);
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
34
27
  var transformHermesLoops_exports = {};
35
- __export(transformHermesLoops_exports, {
36
- transformHermesLoops: () => transformHermesLoops
37
- });
28
+ __export(transformHermesLoops_exports, { transformHermesLoops: () => transformHermesLoops });
38
29
  module.exports = __toCommonJS(transformHermesLoops_exports);
39
30
  var import_magic_string = __toESM(require("magic-string"), 1);
40
31
  var import_oxc_parser = require("oxc-parser");
41
32
  const LOOP_RE = /\b(?:for|while)\s*(?:await\s+)?\(/;
42
33
  const LEXICAL_RE = /\b(?:let|const|class)\b/;
43
34
  function langFor(filename) {
44
- const ext = filename.split("?")[0].split(".").pop() || "js";
45
- if (ext === "ts" || ext === "cts" || ext === "mts") return "ts";
46
- if (ext === "tsx") return "tsx";
47
- return "jsx";
35
+ const ext = filename.split("?")[0].split(".").pop() || "js";
36
+ if (ext === "ts" || ext === "cts" || ext === "mts") return "ts";
37
+ if (ext === "tsx") return "tsx";
38
+ return "jsx";
48
39
  }
49
40
  function collectPatternNames(node, out) {
50
- if (!node || typeof node !== "object") return;
51
- switch (node.type) {
52
- case "Identifier":
53
- out.push(node.name);
54
- return;
55
- case "ObjectPattern":
56
- for (const p of node.properties || []) {
57
- collectPatternNames(p.value ?? p.argument, out);
58
- }
59
- return;
60
- case "ArrayPattern":
61
- for (const el of node.elements || []) collectPatternNames(el, out);
62
- return;
63
- case "AssignmentPattern":
64
- collectPatternNames(node.left, out);
65
- return;
66
- case "RestElement":
67
- collectPatternNames(node.argument, out);
68
- return;
69
- }
41
+ if (!node || typeof node !== "object") return;
42
+ switch (node.type) {
43
+ case "Identifier":
44
+ out.push(node.name);
45
+ return;
46
+ case "ObjectPattern":
47
+ for (const p of node.properties || []) {
48
+ collectPatternNames(p.value ?? p.argument, out);
49
+ }
50
+ return;
51
+ case "ArrayPattern":
52
+ for (const el of node.elements || []) collectPatternNames(el, out);
53
+ return;
54
+ case "AssignmentPattern":
55
+ collectPatternNames(node.left, out);
56
+ return;
57
+ case "RestElement":
58
+ collectPatternNames(node.argument, out);
59
+ return;
60
+ }
70
61
  }
71
- const FUNCTION_TYPES = /* @__PURE__ */new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]);
62
+ const FUNCTION_TYPES = /* @__PURE__ */ new Set([
63
+ "FunctionDeclaration",
64
+ "FunctionExpression",
65
+ "ArrowFunctionExpression"
66
+ ]);
72
67
  function eachChild(node, fn) {
73
- for (const key in node) {
74
- if (key === "type" || key === "start" || key === "end" || key === "parent") continue;
75
- const value = node[key];
76
- if (Array.isArray(value)) {
77
- for (const item of value) {
78
- if (item && typeof item.type === "string") fn(item);
79
- }
80
- } else if (value && typeof value === "object" && typeof value.type === "string") {
81
- fn(value);
82
- }
83
- }
68
+ for (const key in node) {
69
+ if (key === "type" || key === "start" || key === "end" || key === "parent") continue;
70
+ const value = node[key];
71
+ if (Array.isArray(value)) {
72
+ for (const item of value) {
73
+ if (item && typeof item.type === "string") fn(item);
74
+ }
75
+ } else if (value && typeof value === "object" && typeof value.type === "string") {
76
+ fn(value);
77
+ }
78
+ }
84
79
  }
85
80
  function capturesInClosure(body, names) {
86
- let found = false;
87
- function scanInsideFunction(node, shadowed) {
88
- if (found || !node || typeof node !== "object") return;
89
- if (node.type === "Identifier" && names.has(node.name) && !shadowed.has(node.name)) {
90
- found = true;
91
- return;
92
- }
93
- if (FUNCTION_TYPES.has(node.type)) {
94
- const inner = new Set(shadowed);
95
- const params = [];
96
- for (const p of node.params || []) collectPatternNames(p, params);
97
- for (const p of params) inner.add(p);
98
- if (node.id?.name) inner.add(node.id.name);
99
- eachChild(node, c => scanInsideFunction(c, inner));
100
- return;
101
- }
102
- if (node.type === "MemberExpression" && !node.computed) {
103
- scanInsideFunction(node.object, shadowed);
104
- return;
105
- }
106
- if (node.type === "Property" && !node.computed && node.key === node.value) {
107
- scanInsideFunction(node.value, shadowed);
108
- return;
109
- }
110
- eachChild(node, c => scanInsideFunction(c, shadowed));
111
- }
112
- function walk(node) {
113
- if (found || !node || typeof node !== "object") return;
114
- if (FUNCTION_TYPES.has(node.type)) {
115
- const shadowed = /* @__PURE__ */new Set();
116
- const params = [];
117
- for (const p of node.params || []) collectPatternNames(p, params);
118
- for (const p of params) shadowed.add(p);
119
- eachChild(node, c => scanInsideFunction(c, shadowed));
120
- return;
121
- }
122
- eachChild(node, walk);
123
- }
124
- walk(body);
125
- return found;
81
+ let found = false;
82
+ function scanInsideFunction(node, shadowed) {
83
+ if (found || !node || typeof node !== "object") return;
84
+ if (node.type === "Identifier" && names.has(node.name) && !shadowed.has(node.name)) {
85
+ found = true;
86
+ return;
87
+ }
88
+ if (FUNCTION_TYPES.has(node.type)) {
89
+ const inner = new Set(shadowed);
90
+ const params = [];
91
+ for (const p of node.params || []) collectPatternNames(p, params);
92
+ for (const p of params) inner.add(p);
93
+ if (node.id?.name) inner.add(node.id.name);
94
+ eachChild(node, (c) => scanInsideFunction(c, inner));
95
+ return;
96
+ }
97
+ if (node.type === "MemberExpression" && !node.computed) {
98
+ scanInsideFunction(node.object, shadowed);
99
+ return;
100
+ }
101
+ if (node.type === "Property" && !node.computed && node.key === node.value) {
102
+ scanInsideFunction(node.value, shadowed);
103
+ return;
104
+ }
105
+ eachChild(node, (c) => scanInsideFunction(c, shadowed));
106
+ }
107
+ function walk(node) {
108
+ if (found || !node || typeof node !== "object") return;
109
+ if (FUNCTION_TYPES.has(node.type)) {
110
+ const shadowed = /* @__PURE__ */ new Set();
111
+ const params = [];
112
+ for (const p of node.params || []) collectPatternNames(p, params);
113
+ for (const p of params) shadowed.add(p);
114
+ eachChild(node, (c) => scanInsideFunction(c, shadowed));
115
+ return;
116
+ }
117
+ eachChild(node, walk);
118
+ }
119
+ walk(body);
120
+ return found;
126
121
  }
127
122
  function analyzeBody(body, names) {
128
- const facts = {
129
- hasBreak: false,
130
- hasContinue: false,
131
- hasReturn: false,
132
- hasAwait: false,
133
- hasYield: false,
134
- assignsBinding: false,
135
- hasLabeledJump: false
136
- };
137
- function walk(node, inNestedBreakable, inNestedLoop, inFunction) {
138
- if (!node || typeof node !== "object") return;
139
- if (FUNCTION_TYPES.has(node.type)) {
140
- eachChild(node, c => walk(c, inNestedBreakable, inNestedLoop, true));
141
- return;
142
- }
143
- switch (node.type) {
144
- case "BreakStatement":
145
- if (node.label) facts.hasLabeledJump = true;else if (!inNestedBreakable) facts.hasBreak = true;
146
- break;
147
- case "ContinueStatement":
148
- if (node.label) facts.hasLabeledJump = true;else if (!inNestedLoop) facts.hasContinue = true;
149
- break;
150
- case "ReturnStatement":
151
- if (!inFunction) facts.hasReturn = true;
152
- break;
153
- case "AwaitExpression":
154
- if (!inFunction) facts.hasAwait = true;
155
- break;
156
- case "YieldExpression":
157
- if (!inFunction) facts.hasYield = true;
158
- break;
159
- case "AssignmentExpression":
160
- if (node.left?.type === "Identifier" && names.has(node.left.name)) {
161
- facts.assignsBinding = true;
162
- }
163
- break;
164
- case "UpdateExpression":
165
- if (node.argument?.type === "Identifier" && names.has(node.argument.name)) {
166
- facts.assignsBinding = true;
167
- }
168
- break;
169
- }
170
- const isLoop = node.type === "ForStatement" || node.type === "ForOfStatement" || node.type === "ForInStatement" || node.type === "WhileStatement" || node.type === "DoWhileStatement";
171
- const isBreakable = isLoop || node.type === "SwitchStatement";
172
- eachChild(node, c => walk(c, inNestedBreakable || isBreakable, inNestedLoop || isLoop, inFunction));
173
- }
174
- walk(body, false, false, false);
175
- return facts;
123
+ const facts = {
124
+ hasBreak: false,
125
+ hasContinue: false,
126
+ hasReturn: false,
127
+ hasAwait: false,
128
+ hasYield: false,
129
+ assignsBinding: false,
130
+ hasLabeledJump: false
131
+ };
132
+ function walk(node, inNestedBreakable, inNestedLoop, inFunction) {
133
+ if (!node || typeof node !== "object") return;
134
+ if (FUNCTION_TYPES.has(node.type)) {
135
+ eachChild(node, (c) => walk(c, inNestedBreakable, inNestedLoop, true));
136
+ return;
137
+ }
138
+ switch (node.type) {
139
+ case "BreakStatement":
140
+ if (node.label) facts.hasLabeledJump = true;
141
+ else if (!inNestedBreakable) facts.hasBreak = true;
142
+ break;
143
+ case "ContinueStatement":
144
+ if (node.label) facts.hasLabeledJump = true;
145
+ else if (!inNestedLoop) facts.hasContinue = true;
146
+ break;
147
+ case "ReturnStatement":
148
+ if (!inFunction) facts.hasReturn = true;
149
+ break;
150
+ case "AwaitExpression":
151
+ if (!inFunction) facts.hasAwait = true;
152
+ break;
153
+ case "YieldExpression":
154
+ if (!inFunction) facts.hasYield = true;
155
+ break;
156
+ case "AssignmentExpression":
157
+ if (node.left?.type === "Identifier" && names.has(node.left.name)) {
158
+ facts.assignsBinding = true;
159
+ }
160
+ break;
161
+ case "UpdateExpression":
162
+ if (node.argument?.type === "Identifier" && names.has(node.argument.name)) {
163
+ facts.assignsBinding = true;
164
+ }
165
+ break;
166
+ }
167
+ const isLoop = node.type === "ForStatement" || node.type === "ForOfStatement" || node.type === "ForInStatement" || node.type === "WhileStatement" || node.type === "DoWhileStatement";
168
+ const isBreakable = isLoop || node.type === "SwitchStatement";
169
+ eachChild(node, (c) => walk(c, inNestedBreakable || isBreakable, inNestedLoop || isLoop, inFunction));
170
+ }
171
+ walk(body, false, false, false);
172
+ return facts;
176
173
  }
177
174
  function collectBodyLexicalNames(node, out) {
178
- if (!node || typeof node !== "object" || typeof node.type !== "string") return;
179
- if (FUNCTION_TYPES.has(node.type) || node.type === "ClassBody") return;
180
- if (node.type === "VariableDeclaration") {
181
- if (node.kind === "let" || node.kind === "const") {
182
- for (const d of node.declarations || []) collectPatternNames(d.id, out);
183
- }
184
- return;
185
- }
186
- if (node.type === "ClassDeclaration") {
187
- if (node.id?.name) out.push(node.id.name);
188
- return;
189
- }
190
- eachChild(node, c => collectBodyLexicalNames(c, out));
175
+ if (!node || typeof node !== "object" || typeof node.type !== "string") return;
176
+ if (FUNCTION_TYPES.has(node.type) || node.type === "ClassBody") return;
177
+ if (node.type === "VariableDeclaration") {
178
+ if (node.kind === "let" || node.kind === "const") {
179
+ for (const d of node.declarations || []) collectPatternNames(d.id, out);
180
+ }
181
+ return;
182
+ }
183
+ if (node.type === "ClassDeclaration") {
184
+ if (node.id?.name) out.push(node.id.name);
185
+ return;
186
+ }
187
+ eachChild(node, (c) => collectBodyLexicalNames(c, out));
191
188
  }
192
- const LOOP_TYPES = /* @__PURE__ */new Set(["ForStatement", "ForOfStatement", "ForInStatement", "WhileStatement", "DoWhileStatement"]);
189
+ const LOOP_TYPES = /* @__PURE__ */ new Set([
190
+ "ForStatement",
191
+ "ForOfStatement",
192
+ "ForInStatement",
193
+ "WhileStatement",
194
+ "DoWhileStatement"
195
+ ]);
193
196
  function headDeclaration(node) {
194
- if (node.type === "ForStatement") return node.init;
195
- if (node.type === "ForOfStatement" || node.type === "ForInStatement") return node.left;
196
- return null;
197
+ if (node.type === "ForStatement") return node.init;
198
+ if (node.type === "ForOfStatement" || node.type === "ForInStatement") return node.left;
199
+ return null;
197
200
  }
198
201
  function transformOnce(code, filename) {
199
- const parsed = (0, import_oxc_parser.parseSync)(filename, code, {
200
- lang: langFor(filename)
201
- });
202
- if (!parsed?.program || parsed.errors?.length) return null;
203
- const candidates = [];
204
- function findLoops(node, insideCandidate) {
205
- if (!node || typeof node !== "object") return;
206
- let isCandidate = false;
207
- if (LOOP_TYPES.has(node.type) && node.body) {
208
- const names = [];
209
- const decl = headDeclaration(node);
210
- if (decl?.type === "VariableDeclaration" && (decl.kind === "let" || decl.kind === "const")) {
211
- for (const d of decl.declarations || []) collectPatternNames(d.id, names);
212
- }
213
- const shared = [...names];
214
- collectBodyLexicalNames(node.body, shared);
215
- if (shared.length && capturesInClosure(node.body, new Set(shared))) {
216
- isCandidate = true;
217
- if (!insideCandidate) candidates.push({
218
- node,
219
- names
220
- });
221
- }
222
- }
223
- eachChild(node, c => findLoops(c, insideCandidate || isCandidate));
224
- }
225
- findLoops(parsed.program, false);
226
- if (!candidates.length) return null;
227
- const s = new import_magic_string.default(code);
228
- let counter = 0;
229
- let changed = false;
230
- for (const {
231
- node,
232
- names
233
- } of candidates) {
234
- const nameSet = new Set(names);
235
- const facts = analyzeBody(node.body, nameSet);
236
- if (facts.hasYield || facts.assignsBinding || facts.hasLabeledJump) continue;
237
- const fnName = `_hermesLoop${counter++}`;
238
- const params = names.join(", ");
239
- let bodyText = code.slice(node.body.start, node.body.end);
240
- if (node.body.type !== "BlockStatement") {
241
- bodyText = `{ ${bodyText} }`;
242
- }
243
- if (facts.hasBreak || facts.hasReturn || facts.hasContinue) {
244
- bodyText = rewriteJumps(bodyText, node.body, code, nameSet);
245
- }
246
- const asyncKw = facts.hasAwait ? "async " : "";
247
- const awaitKw = facts.hasAwait ? "await " : "";
248
- let call = `${awaitKw}${fnName}(${params})`;
249
- if (facts.hasBreak || facts.hasReturn) {
250
- const checks = [];
251
- if (facts.hasBreak) checks.push("if (_r === 1) break;");
252
- if (facts.hasReturn) checks.push("if (_r) return _r.v;");
253
- call = `{ var _r = ${call}; ${checks.join(" ")} }`;
254
- } else {
255
- call = `{ ${call}; }`;
256
- }
257
- s.overwrite(node.body.start, node.body.end, call);
258
- s.appendLeft(node.start, `{
202
+ const parsed = (0, import_oxc_parser.parseSync)(filename, code, { lang: langFor(filename) });
203
+ if (!parsed?.program || parsed.errors?.length) return null;
204
+ const candidates = [];
205
+ function findLoops(node, insideCandidate) {
206
+ if (!node || typeof node !== "object") return;
207
+ let isCandidate = false;
208
+ if (LOOP_TYPES.has(node.type) && node.body) {
209
+ const names = [];
210
+ const decl = headDeclaration(node);
211
+ if (decl?.type === "VariableDeclaration" && (decl.kind === "let" || decl.kind === "const")) {
212
+ for (const d of decl.declarations || []) collectPatternNames(d.id, names);
213
+ }
214
+ const shared = [...names];
215
+ collectBodyLexicalNames(node.body, shared);
216
+ if (shared.length && capturesInClosure(node.body, new Set(shared))) {
217
+ isCandidate = true;
218
+ if (!insideCandidate) candidates.push({
219
+ node,
220
+ names
221
+ });
222
+ }
223
+ }
224
+ eachChild(node, (c) => findLoops(c, insideCandidate || isCandidate));
225
+ }
226
+ findLoops(parsed.program, false);
227
+ if (!candidates.length) return null;
228
+ const s = new import_magic_string.default(code);
229
+ let counter = 0;
230
+ let changed = false;
231
+ for (const { node, names } of candidates) {
232
+ const nameSet = new Set(names);
233
+ const facts = analyzeBody(node.body, nameSet);
234
+ if (facts.hasYield || facts.assignsBinding || facts.hasLabeledJump) continue;
235
+ const fnName = `_hermesLoop${counter++}`;
236
+ const params = names.join(", ");
237
+ let bodyText = code.slice(node.body.start, node.body.end);
238
+ if (node.body.type !== "BlockStatement") {
239
+ bodyText = `{ ${bodyText} }`;
240
+ }
241
+ if (facts.hasBreak || facts.hasReturn || facts.hasContinue) {
242
+ bodyText = rewriteJumps(bodyText, node.body, code, nameSet);
243
+ }
244
+ const asyncKw = facts.hasAwait ? "async " : "";
245
+ const awaitKw = facts.hasAwait ? "await " : "";
246
+ let call = `${awaitKw}${fnName}(${params})`;
247
+ if (facts.hasBreak || facts.hasReturn) {
248
+ const checks = [];
249
+ if (facts.hasBreak) checks.push("if (_r === 1) break;");
250
+ if (facts.hasReturn) checks.push("if (_r) return _r.v;");
251
+ call = `{ var _r = ${call}; ${checks.join(" ")} }`;
252
+ } else {
253
+ call = `{ ${call}; }`;
254
+ }
255
+ s.overwrite(node.body.start, node.body.end, call);
256
+ s.appendLeft(node.start, `{
259
257
  var ${fnName} = ${asyncKw}(${params}) => ${bodyText};
260
258
  `);
261
- s.appendLeft(node.end, "\n}");
262
- changed = true;
263
- }
264
- if (!changed) return null;
265
- return {
266
- code: s.toString(),
267
- map: s.generateMap({
268
- hires: true,
269
- source: filename,
270
- includeContent: false
271
- })
272
- };
259
+ s.appendLeft(node.end, "\n}");
260
+ changed = true;
261
+ }
262
+ if (!changed) return null;
263
+ return {
264
+ code: s.toString(),
265
+ map: s.generateMap({
266
+ hires: true,
267
+ source: filename,
268
+ includeContent: false
269
+ })
270
+ };
273
271
  }
274
272
  function rewriteJumps(bodyText, bodyNode, code, names) {
275
- const offset = bodyNode.start;
276
- const s = new import_magic_string.default(bodyText);
277
- const pad = bodyNode.type === "BlockStatement" ? 0 : 2;
278
- function walk(node, inNestedBreakable, inNestedLoop, inFunction) {
279
- if (!node || typeof node !== "object") return;
280
- if (FUNCTION_TYPES.has(node.type)) {
281
- eachChild(node, c => walk(c, inNestedBreakable, inNestedLoop, true));
282
- return;
283
- }
284
- if (node.type === "BreakStatement" && !node.label && !inNestedBreakable) {
285
- s.overwrite(node.start - offset + pad, node.end - offset + pad, "return 1;");
286
- return;
287
- }
288
- if (node.type === "ContinueStatement" && !node.label && !inNestedLoop) {
289
- s.overwrite(node.start - offset + pad, node.end - offset + pad, "return;");
290
- return;
291
- }
292
- if (node.type === "ReturnStatement" && !inFunction) {
293
- const arg = node.argument;
294
- const replacement = arg ? `return { v: ${code.slice(arg.start, arg.end)} };` : "return { v: undefined };";
295
- s.overwrite(node.start - offset + pad, node.end - offset + pad, replacement);
296
- return;
297
- }
298
- const isLoop = node.type === "ForStatement" || node.type === "ForOfStatement" || node.type === "ForInStatement" || node.type === "WhileStatement" || node.type === "DoWhileStatement";
299
- const isBreakable = isLoop || node.type === "SwitchStatement";
300
- eachChild(node, c => walk(c, inNestedBreakable || isBreakable, inNestedLoop || isLoop, inFunction));
301
- }
302
- walk(bodyNode, false, false, false);
303
- return s.toString();
273
+ const offset = bodyNode.start;
274
+ const s = new import_magic_string.default(bodyText);
275
+ const pad = bodyNode.type === "BlockStatement" ? 0 : 2;
276
+ function walk(node, inNestedBreakable, inNestedLoop, inFunction) {
277
+ if (!node || typeof node !== "object") return;
278
+ if (FUNCTION_TYPES.has(node.type)) {
279
+ eachChild(node, (c) => walk(c, inNestedBreakable, inNestedLoop, true));
280
+ return;
281
+ }
282
+ if (node.type === "BreakStatement" && !node.label && !inNestedBreakable) {
283
+ s.overwrite(node.start - offset + pad, node.end - offset + pad, "return 1;");
284
+ return;
285
+ }
286
+ if (node.type === "ContinueStatement" && !node.label && !inNestedLoop) {
287
+ s.overwrite(node.start - offset + pad, node.end - offset + pad, "return;");
288
+ return;
289
+ }
290
+ if (node.type === "ReturnStatement" && !inFunction) {
291
+ const arg = node.argument;
292
+ const replacement = arg ? `return { v: ${code.slice(arg.start, arg.end)} };` : "return { v: undefined };";
293
+ s.overwrite(node.start - offset + pad, node.end - offset + pad, replacement);
294
+ return;
295
+ }
296
+ const isLoop = node.type === "ForStatement" || node.type === "ForOfStatement" || node.type === "ForInStatement" || node.type === "WhileStatement" || node.type === "DoWhileStatement";
297
+ const isBreakable = isLoop || node.type === "SwitchStatement";
298
+ eachChild(node, (c) => walk(c, inNestedBreakable || isBreakable, inNestedLoop || isLoop, inFunction));
299
+ }
300
+ walk(bodyNode, false, false, false);
301
+ return s.toString();
304
302
  }
305
303
  function transformHermesLoops(code, filename) {
306
- if (!LOOP_RE.test(code) || !LEXICAL_RE.test(code)) return null;
307
- let current = code;
308
- const maps = [];
309
- for (let i = 0; i < 10; i++) {
310
- const next = transformOnce(current, filename);
311
- if (!next) break;
312
- current = next.code;
313
- maps.push(next.map);
314
- }
315
- return maps.length ? {
316
- code: current,
317
- maps
318
- } : null;
319
- }
304
+ if (!LOOP_RE.test(code) || !LEXICAL_RE.test(code)) return null;
305
+ let current = code;
306
+ const maps = [];
307
+ for (let i = 0; i < 10; i++) {
308
+ const next = transformOnce(current, filename);
309
+ if (!next) break;
310
+ current = next.code;
311
+ maps.push(next.map);
312
+ }
313
+ return maps.length ? {
314
+ code: current,
315
+ maps
316
+ } : null;
317
+ }