Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions compiler/crates/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,46 @@ Each line names the failure mode and a sketch of where to look.
`TSTypeParameterInstantiation` in `convert_ast.rs` AND deserialization
in `convert_ast_reverse.rs::convert_ts_type_from_json`.

## Cross-frontend: TypeScript module interop statements

Three `todo-ts-*` fixtures pin how TS module-interop statements
(`import x = require(...)`, `export = x`, `export as namespace X`) must
behave: the statement is preserved in output and the file's functions
still compile. The TS reference does both. The three frontends share
the broken symptom today via three different root causes:

- **Babel/NAPI** throws `Failed to parse AST JSON: unknown variant
TSImportEqualsDeclaration` (etc.) because the typed AST's
`#[serde(tag = "type")]` enums have no catch-all, failing the whole
file. The same root cause reds both `react_compiler_ast` fixture
tests (`round_trip` and `scope_resolution_rename`) under
`test-babel-ast.sh`.
- **SWC**'s converter explicitly rewrites all three statements to
`EmptyStatement` (`react_compiler_swc/src/convert_ast.rs`,
`TsImportEquals` / `TsExportAssignment` / `TsNamespaceExport` arms),
erasing them from output with no error and no event.
- **OXC** `todo!()`-panics in `react_compiler_oxc/src/convert_ast.rs`
(arms of the same three names; the sibling `TSGlobalDeclaration` arm
is also unmodeled but unreachable from Babel-parsed fixtures, which
represent `declare global` as `TSModuleDeclaration`). Deferred.

Known-red until the fixes land: the three fixtures fail Babel and SWC
e2e and `test-babel-ast.sh`, and the e2e totals elsewhere in this doc
are stale by +3 fixtures.

Planned fixes: (1) Babel path: unknown-statement tolerance in
`react_compiler_ast` (untagged catch-all carrying the raw node,
preserved through codegen and re-serialization); (2) SWC: replace the
`EmptyStatement` arms with real preservation; mapping unknown nodes to
`EmptyStatement` is the bug, not a fallback. Rename each fixture to
drop the `todo-` prefix as it goes green end to end, and update the
`SproutTodoFilter` entry for the namespace fixture in the same change
(the filter matches by basename).

- `todo-ts-import-equals-declaration.ts`
- `todo-ts-export-assignment.ts`
- `todo-ts-namespace-export-declaration.ts`

## Babel

**TODO: scope this out.** Babel is at 1788 / 1795 (7 failures). These have
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

## Input

```javascript
function useValue(value: number) {
return [value + 1];
}

export = useValue;

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime";
function useValue(value) {
const $ = _c(2);
const t0 = value + 1;
let t1;
if ($[0] !== t0) {
t1 = [t0];
$[0] = t0;
$[1] = t1;
} else {
t1 = $[1];
}
return t1;
}

export = useValue;

```

### Eval output
(kind: exception) Fixture not implemented
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function useValue(value: number) {
return [value + 1];
}

export = useValue;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

## Input

```javascript
import lib = require('shared-runtime');

function useValue(value: number) {
return lib.identity(value);
}

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime";
import lib = require("shared-runtime");

function useValue(value) {
const $ = _c(2);
let t0;
if ($[0] !== value) {
t0 = lib.identity(value);
$[0] = value;
$[1] = t0;
} else {
t0 = $[1];
}
return t0;
}

```

### Eval output
(kind: exception) Fixture not implemented
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import lib = require('shared-runtime');

function useValue(value: number) {
return lib.identity(value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

## Input

```javascript
export as namespace Foo;

function useValue(value: number) {
return {value};
}

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime";
export as namespace Foo;

function useValue(value) {
const $ = _c(2);
let t0;
if ($[0] !== value) {
t0 = { value };
$[0] = value;
$[1] = t0;
} else {
t0 = $[1];
}
return t0;
}

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export as namespace Foo;

function useValue(value: number) {
return {value};
}
9 changes: 9 additions & 0 deletions compiler/packages/snap/src/SproutTodoFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ const skipFilter = new Set([
'todo-round3_outlined_naming',
'todo-round3_promote_used_temps',

/**
* `export as namespace` is a .d.ts-shaped construct; sprout's second-stage
* evaluator transform cannot evaluate it. The sibling todo-ts-* interop
* fixtures evaluate fine (they transform to CJS) and are deliberately not
* skipped. Remove or update this entry when the fixture is renamed after
* the Rust fix lands (the filter matches by basename).
*/
'todo-ts-namespace-export-declaration',

/**
* Observable different in logging between Forget and non-Forget
*/
Expand Down
Loading