From 814a4186459eb79ed9bc6f22de4a4f75ff77558c Mon Sep 17 00:00:00 2001 From: Mike Vitousek Date: Wed, 12 Jun 2024 15:31:59 -0700 Subject: [PATCH] [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 --- .../src/HIR/BuildHIR.ts | 27 ++++++++++++++++++- .../src/HIR/HIR.ts | 4 +-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts index 826b720300..e5a067018d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -1668,6 +1668,15 @@ function lowerExpression( const left = lowerExpressionToTemporary(builder, leftPath); const right = lowerExpressionToTemporary(builder, expr.get("right")); const operator = expr.node.operator; + if (operator === "|>") { + builder.errors.push({ + reason: `(BuildHIR::lowerExpression) Pipe operator not supported`, + severity: ErrorSeverity.Todo, + loc: leftPath.node.loc ?? null, + suggestions: null, + }); + return { kind: "UnsupportedNode", node: exprNode, loc: exprLoc }; + } return { kind: "BinaryExpression", operator, @@ -1893,7 +1902,9 @@ function lowerExpression( ); } - const operators: { [key: string]: t.BinaryExpression["operator"] } = { + const operators: { + [key: string]: Exclude">; + } = { "+=": "+", "-=": "-", "/=": "/", @@ -2307,6 +2318,20 @@ function lowerExpression( }); return { kind: "UnsupportedNode", node: expr.node, loc: exprLoc }; } + } else if (expr.node.operator === "throw") { + builder.errors.push({ + reason: `Throw expressions are not supported`, + severity: ErrorSeverity.InvalidJS, + loc: expr.node.loc ?? null, + suggestions: [ + { + description: "Remove this line", + range: [expr.node.start!, expr.node.end!], + op: CompilerSuggestionOperation.Remove, + }, + ], + }); + return { kind: "UnsupportedNode", node: expr.node, loc: exprLoc }; } else { return { kind: "UnaryExpression", diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts index d544269869..2294335034 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts @@ -866,7 +866,7 @@ export type InstructionValue = | JSXText | { kind: "BinaryExpression"; - operator: t.BinaryExpression["operator"]; + operator: Exclude">; left: Place; right: Place; loc: SourceLocation; @@ -881,7 +881,7 @@ export type InstructionValue = | MethodCall | { kind: "UnaryExpression"; - operator: t.UnaryExpression["operator"]; + operator: Exclude; value: Place; loc: SourceLocation; }