From 81e1ee7476a68fdf13c63d3002e5ef1b699b6842 Mon Sep 17 00:00:00 2001 From: Joseph Savona <6425824+josephsavona@users.noreply.github.com> Date: Wed, 9 Jul 2025 22:21:02 -0700 Subject: [PATCH] [compiler] Support inline enums (flow/ts), type declarations (#33747) Supports inline enum declarations in both Flow and TS by treating the node as pass-through (enums can't capture values mutably). Related, this PR extends the set of type-related declarations that we ignore. Previously we threw a todo for things like DeclareClass or DeclareVariable, but these are type related and can simply be dropped just like we dropped TypeAlias. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33747). * #33753 * #33752 * #33751 * #33750 * #33748 * __->__ #33747 --- .../src/HIR/BuildHIR.ts | 25 +++++--- .../src/HIR/PrintHIR.ts | 3 +- .../ReactiveScopes/PruneNonEscapingScopes.ts | 14 +++-- .../compiler/flow-enum-inline.expect.md | 60 +++++++++++++++++++ .../fixtures/compiler/flow-enum-inline.js | 18 ++++++ .../compiler/ts-enum-inline.expect.md | 59 ++++++++++++++++++ .../fixtures/compiler/ts-enum-inline.tsx | 17 ++++++ 7 files changed, 179 insertions(+), 17 deletions(-) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/flow-enum-inline.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/flow-enum-inline.js create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ts-enum-inline.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ts-enum-inline.tsx 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 efcfecce78..5bcf27b333 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -1388,10 +1388,13 @@ function lowerStatement( }); return; } - case 'TypeAlias': - case 'TSInterfaceDeclaration': - case 'TSTypeAliasDeclaration': { - // We do not preserve type annotations/syntax through transformation + case 'EnumDeclaration': + case 'TSEnumDeclaration': { + lowerValueToTemporary(builder, { + kind: 'UnsupportedNode', + loc: stmtPath.node.loc ?? GeneratedSource, + node: stmtPath.node, + }); return; } case 'DeclareClass': @@ -1404,15 +1407,19 @@ function lowerStatement( case 'DeclareOpaqueType': case 'DeclareTypeAlias': case 'DeclareVariable': - case 'EnumDeclaration': + case 'InterfaceDeclaration': + case 'OpaqueType': + case 'TSDeclareFunction': + case 'TSInterfaceDeclaration': + case 'TSTypeAliasDeclaration': + case 'TypeAlias': { + // We do not preserve type annotations/syntax through transformation + return; + } case 'ExportAllDeclaration': case 'ExportDefaultDeclaration': case 'ExportNamedDeclaration': case 'ImportDeclaration': - case 'InterfaceDeclaration': - case 'OpaqueType': - case 'TSDeclareFunction': - case 'TSEnumDeclaration': case 'TSExportAssignment': case 'TSImportEqualsDeclaration': case 'TSModuleDeclaration': diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts index caaced124e..23471a00b0 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import generate from '@babel/generator'; import {CompilerError} from '../CompilerError'; import {printReactiveScopeSummary} from '../ReactiveScopes/PrintReactiveFunction'; import DisjointSet from '../Utils/DisjointSet'; @@ -466,7 +465,7 @@ export function printInstructionValue(instrValue: ReactiveValue): string { break; } case 'UnsupportedNode': { - value = `UnsupportedNode(${generate(instrValue.node).code})`; + value = `UnsupportedNode ${instrValue.node.type}`; break; } case 'LoadLocal': { diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneNonEscapingScopes.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneNonEscapingScopes.ts index 52a0312dcd..8484a1ca8d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneNonEscapingScopes.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneNonEscapingScopes.ts @@ -829,12 +829,14 @@ class CollectDependenciesVisitor extends ReactiveFunctionVisitor< }; } case 'UnsupportedNode': { - CompilerError.invariant(false, { - reason: `Unexpected unsupported node`, - description: null, - loc: value.loc, - suggestions: null, - }); + const lvalues = []; + if (lvalue !== null) { + lvalues.push({place: lvalue, level: MemoizationLevel.Never}); + } + return { + lvalues, + rvalues: [], + }; } default: { assertExhaustive( diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/flow-enum-inline.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/flow-enum-inline.expect.md new file mode 100644 index 0000000000..dfbf4fbfd9 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/flow-enum-inline.expect.md @@ -0,0 +1,60 @@ + +## Input + +```javascript +// @flow +function Component(props) { + enum Bool { + True = 'true', + False = 'false', + } + + let bool: Bool = Bool.False; + if (props.value) { + bool = Bool.True; + } + return