Compare commits

...

1 Commits

Author SHA1 Message Date
Joe Savona
8a7e8557da [compiler] Support inline enums (flow/ts), type declarations
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.
2025-07-09 22:20:16 -07:00
7 changed files with 179 additions and 17 deletions

View File

@@ -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':

View File

@@ -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': {

View File

@@ -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(

View File

@@ -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 <div>{bool}</div>;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: true}],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
function Component(props) {
const $ = _c(2);
enum Bool {
True = "true",
False = "false",
}
let bool = Bool.False;
if (props.value) {
bool = Bool.True;
}
let t0;
if ($[0] !== bool) {
t0 = <div>{bool}</div>;
$[0] = bool;
$[1] = t0;
} else {
t0 = $[1];
}
return t0;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: true }],
};
```
### Eval output
(kind: exception) Bool is not defined

View File

@@ -0,0 +1,18 @@
// @flow
function Component(props) {
enum Bool {
True = 'true',
False = 'false',
}
let bool: Bool = Bool.False;
if (props.value) {
bool = Bool.True;
}
return <div>{bool}</div>;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: true}],
};

View File

@@ -0,0 +1,59 @@
## Input
```javascript
function Component(props) {
enum Bool {
True = 'true',
False = 'false',
}
let bool: Bool = Bool.False;
if (props.value) {
bool = Bool.True;
}
return <div>{bool}</div>;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: true}],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
function Component(props) {
const $ = _c(2);
enum Bool {
True = "true",
False = "false",
}
let bool = Bool.False;
if (props.value) {
bool = Bool.True;
}
let t0;
if ($[0] !== bool) {
t0 = <div>{bool}</div>;
$[0] = bool;
$[1] = t0;
} else {
t0 = $[1];
}
return t0;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: true }],
};
```
### Eval output
(kind: ok) <div>true</div>

View File

@@ -0,0 +1,17 @@
function Component(props) {
enum Bool {
True = 'true',
False = 'false',
}
let bool: Bool = Bool.False;
if (props.value) {
bool = Bool.True;
}
return <div>{bool}</div>;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{value: true}],
};