@samitouri / QOS-React-1 / commits / 7e9f6ecfea

[patch] Make holey array handling compatible with older babel versions

--- Copied from comments Older versions of babel have a validation bug fixed by - https://github.com/babel/babel/pull/10917 - (code pointer) https://github.com/babel/babel/commit/e7b80a2cb93cf28010207fc3cdd19b4568ca35b9#diff-19b555d2f3904c206af406540d9df200b1e16befedb83ff39ebfcbd876f7fa8aL52 Link to buggy older version (observe that elements must be PatternLikes here) https://github.com/babel/babel/blob/v7.7.4/packages/babel-types/src/definitions/es2015.js#L50-L53 Link to newer versions with correct validation (observe elements can be PatternLike | null) https://github.com/babel/babel/blob/v7.23.0/packages/babel-types/src/definitions/core.ts#L1306-L1311 Tested on 3000+ components in fb: P898166848 > Unexpected Errors > (count = 0) [patch] Make holey array handling compatible with older babel versions --- Copied from comments Older versions of babel have a validation bug fixed by - https://github.com/babel/babel/pull/10917 - (code pointer) https://github.com/babel/babel/commit/e7b80a2cb93cf28010207fc3cdd19b4568ca35b9#diff-19b555d2f3904c206af406540d9df200b1e16befedb83ff39ebfcbd876f7fa8aL52 Link to buggy older version (observe that elements must be PatternLikes here) https://github.com/babel/babel/blob/v7.7.4/packages/babel-types/src/definitions/es2015.js#L50-L53 Link to newer versions with correct validation (observe elements can be PatternLike | null) https://github.com/babel/babel/blob/v7.23.0/packages/babel-types/src/definitions/core.ts#L1306-L1311 Tested on 3000+ components in fb: P898166848 > Unexpected Errors > (count = 0)

Mofei Zhang committed Dec 6, 2023 at 13:20 UTC 7e9f6ecfea52a750077cc36c869185123bcd635e
5 files changed +40 -74
compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts
-17
@@ -1456,14 +1456,6 @@ function lowerExpression(
1456 elements.push({
1457 kind: "Hole",
1458 });
1459 - if (builder.environment.config.bailoutOnHoleyArrays) {
1460 - builder.errors.push({
1461 - reason: `(BuildHIR::lower) Fix babel holey array backward compatibility.`,
1462 - severity: ErrorSeverity.Todo,
1463 - loc: expr.node.loc ?? null,
1464 - suggestions: null,
1465 - });
1466 - }
1459 continue;
1460 } else if (element.isExpression()) {
1461 elements.push(lowerExpressionToTemporary(builder, element));
@@ -3289,15 +3281,6 @@ function lowerAssignment(
3281 items.push({
3282 kind: "Hole",
3283 });
3292 -
3293 - if (builder.environment.config.bailoutOnHoleyArrays) {
3294 - builder.errors.push({
3295 - reason: `(BuildHIR::lower) Fix babel holey array backward compatibility.`,
3296 - severity: ErrorSeverity.Todo,
3297 - loc: lvalue.node.loc ?? null,
3298 - suggestions: null,
3299 - });
3300 - }
3284 continue;
3285 }
3286 if (element.isRestElement()) {
compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts
-24
@@ -256,30 +256,6 @@ const EnvironmentConfigSchema = z.object({
256 // Enable validation of mutable ranges
257 assertValidMutableRanges: z.boolean().default(false),
258
259 - /*
260 - *
261 - * Instead of handling holey arrays, bail out with a TODO error.
262 - *
263 - * Older versions of babel seem to have inconsistent handling of holey arrays,
264 - * at least when paired with HermesParser. When using these versions, we should
265 - * bail out instead of throwing a Babel validation error.
266 - *
267 - * The babel ast definition for array elements changed from Array<PatternLike>
268 - * to Array<PatternLike | null>. Older versions does not expect null in the
269 - * ArrayPattern ast and will throw a validation error.
270 - *
271 - * - HermesParser will parse [, b] into [NodePath<null>, NodePath<Identifier>]
272 - * - Forget will try to preserve this holey array when we codegen back to js
273 - * (e.g. we call a babel builder function arrayPattern([null, identifier]))
274 - * - Babel will fail with `TypeError: Property elements[0] of ArrayPattern
275 - * expected node to be of a type ["PatternLike"] but instead got null`
276 - *
277 - * PR that changed the AST definition
278 - * https://github.com/babel/babel/pull/10917/files#diff-19b555d2f3904c206af406540d9df200b1e16befedb83ff39ebfcbd876f7fa8aL52-R56
279 - *
280 - */
281 - bailoutOnHoleyArrays: z.boolean().default(false),
282 -
259 /*
260 * Enable emitting "change variables" which store the result of whether a particular
261 * reactive scope dependency has changed since the scope was last executed.
compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+40 -8
@@ -10,6 +10,7 @@ import { pruneUnusedLValues, pruneUnusedLabels, renameVariables } from ".";
10 import { CompilerError, ErrorSeverity } from "../CompilerError";
11 import { Environment, EnvironmentConfig, ExternalFunction } from "../HIR";
12 import {
13 + ArrayPattern,
14 BlockId,
15 GeneratedSource,
16 Identifier,
@@ -1827,20 +1828,51 @@ function codegenObjectPropertyKey(
1828 }
1829 }
1830
1831 +function codegenArrayPattern(
1832 + cx: Context,
1833 + pattern: ArrayPattern
1834 +): t.ArrayPattern {
1835 + const hasHoles = !pattern.items.every((e) => e.kind !== "Hole");
1836 + if (hasHoles) {
1837 + const result = t.arrayPattern([]);
1838 + /*
1839 + * Older versions of babel have a validation bug fixed by
1840 + * https://github.com/babel/babel/pull/10917
1841 + * https://github.com/babel/babel/commit/e7b80a2cb93cf28010207fc3cdd19b4568ca35b9#diff-19b555d2f3904c206af406540d9df200b1e16befedb83ff39ebfcbd876f7fa8aL52
1842 + *
1843 + * Link to buggy older version (observe that elements must be PatternLikes here)
1844 + * https://github.com/babel/babel/blob/v7.7.4/packages/babel-types/src/definitions/es2015.js#L50-L53
1845 + *
1846 + * Link to newer versions with correct validation (observe elements can be PatternLike | null)
1847 + * https://github.com/babel/babel/blob/v7.23.0/packages/babel-types/src/definitions/core.ts#L1306-L1311
1848 + */
1849 + for (const item of pattern.items) {
1850 + if (item.kind === "Hole") {
1851 + result.elements.push(null);
1852 + } else {
1853 + result.elements.push(codegenLValue(cx, item));
1854 + }
1855 + }
1856 + return result;
1857 + } else {
1858 + return t.arrayPattern(
1859 + pattern.items.map((item) => {
1860 + if (item.kind === "Hole") {
1861 + return null;
1862 + }
1863 + return codegenLValue(cx, item);
1864 + })
1865 + );
1866 + }
1867 +}
1868 +
1869 function codegenLValue(
1870 cx: Context,
1871 pattern: Pattern | Place | SpreadPattern
1872 ): t.ArrayPattern | t.ObjectPattern | t.RestElement | t.Identifier {
1873 switch (pattern.kind) {
1874 case "ArrayPattern": {
1836 - return t.arrayPattern(
1837 - pattern.items.map((item) => {
1838 - if (item.kind === "Hole") {
1839 - return null;
1840 - }
1841 - return codegenLValue(cx, item);
1842 - })
1843 - );
1875 + return codegenArrayPattern(cx, pattern);
1876 }
1877 case "ObjectPattern": {
1878 return t.objectPattern(
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.backwards-compatible-holey-arrays.expect.md deleted
-20
@@ -1,20 +0,0 @@
1 -
2 -## Input
3 -
4 -```javascript
5 -// @bailoutOnHoleyArrays
6 -
7 -function Component() {
8 - return [1, , 3];
9 -}
10 -
11 -```
12 -
13 -
14 -## Error
15 -
16 -```
17 -[ReactForget] Todo: (BuildHIR::lower) Fix babel holey array backward compatibility. (4:4)
18 -```
19 -
20 -
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.backwards-compatible-holey-arrays.js deleted
-5
@@ -1,5 +0,0 @@
1 -// @bailoutOnHoleyArrays
2 -
3 -function Component() {
4 - return [1, , 3];
5 -}