@samitouri / QOS-React-1 / commits / 814a418645

[compiler] Make unary and binary operator types more precise

Summary: Minor change inspired by #29863: the BuildHIR pass ensures that Binary and UnaryOperator nodes only use a limited set of the operators that babel's operator types represent, which that pr relies on for safe reorderability, but the type of those HIR nodes admits the other operators. For example, even though you can't build an HIR UnaryOperator with `delete` as the operator, it is a valid HIR node--and if we made a mistaken change that let you build such a node, it would be unsafe to reorder. This pr makes the typing of operators stricter to prevent that. ghstack-source-id: 9bf3b1a37eae3f14c0e9fb42bb3ece522b317d98 Pull Request resolved: https://github.com/facebook/react/pull/29880

Mike Vitousek committed Jun 12, 2024 at 15:31 UTC 814a4186459eb79ed9bc6f22de4a4f75ff77558c
2 files changed +28 -3
compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts
+26 -1
@@ -1668,6 +1668,15 @@ function lowerExpression(
1668 const left = lowerExpressionToTemporary(builder, leftPath);
1669 const right = lowerExpressionToTemporary(builder, expr.get("right"));
1670 const operator = expr.node.operator;
1671 + if (operator === "|>") {
1672 + builder.errors.push({
1673 + reason: `(BuildHIR::lowerExpression) Pipe operator not supported`,
1674 + severity: ErrorSeverity.Todo,
1675 + loc: leftPath.node.loc ?? null,
1676 + suggestions: null,
1677 + });
1678 + return { kind: "UnsupportedNode", node: exprNode, loc: exprLoc };
1679 + }
1680 return {
1681 kind: "BinaryExpression",
1682 operator,
@@ -1893,7 +1902,9 @@ function lowerExpression(
1902 );
1903 }
1904
1896 - const operators: { [key: string]: t.BinaryExpression["operator"] } = {
1905 + const operators: {
1906 + [key: string]: Exclude<t.BinaryExpression["operator"], "|>">;
1907 + } = {
1908 "+=": "+",
1909 "-=": "-",
1910 "/=": "/",
@@ -2307,6 +2318,20 @@ function lowerExpression(
2318 });
2319 return { kind: "UnsupportedNode", node: expr.node, loc: exprLoc };
2320 }
2321 + } else if (expr.node.operator === "throw") {
2322 + builder.errors.push({
2323 + reason: `Throw expressions are not supported`,
2324 + severity: ErrorSeverity.InvalidJS,
2325 + loc: expr.node.loc ?? null,
2326 + suggestions: [
2327 + {
2328 + description: "Remove this line",
2329 + range: [expr.node.start!, expr.node.end!],
2330 + op: CompilerSuggestionOperation.Remove,
2331 + },
2332 + ],
2333 + });
2334 + return { kind: "UnsupportedNode", node: expr.node, loc: exprLoc };
2335 } else {
2336 return {
2337 kind: "UnaryExpression",
compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
+2 -2
@@ -866,7 +866,7 @@ export type InstructionValue =
866 | JSXText
867 | {
868 kind: "BinaryExpression";
869 - operator: t.BinaryExpression["operator"];
869 + operator: Exclude<t.BinaryExpression["operator"], "|>">;
870 left: Place;
871 right: Place;
872 loc: SourceLocation;
@@ -881,7 +881,7 @@ export type InstructionValue =
881 | MethodCall
882 | {
883 kind: "UnaryExpression";
884 - operator: t.UnaryExpression["operator"];
884 + operator: Exclude<t.UnaryExpression["operator"], "throw" | "delete">;
885 value: Place;
886 loc: SourceLocation;
887 }