Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
78f5c50
Notify FragmentInstance of added/removed text (#35637)
jackpope Feb 11, 2026
cd515d7
Minor DOM FragmentInstance refactors (#35641)
jackpope Feb 11, 2026
892c686
[fiber] bugfix - don't show <Offscreen> in error message. (#35763)
rickhanlonii Feb 11, 2026
8374c2a
[DevTools] Remove experimental __IS_INTERNAL_MCP_BUILD__ flag and rel…
hoxyq Feb 11, 2026
705055d
[DevTools] Enable Suspense tab by default (#35768)
eps1lon Feb 12, 2026
6066c78
[DevTools] Dedicated empty state for roots that aren't suspended by a…
eps1lon Feb 12, 2026
03ca38e
[DevTools] Check suspense child node presence in parentSuspense.child…
hoxyq Feb 13, 2026
e8c6362
[eslint-plugin-react-hooks] Add ESLint v10 support (#35720)
azat-io Feb 13, 2026
47d1ad1
[Flight] Skip `transferReferencedDebugInfo` during debug info resolut…
unstubbable Feb 16, 2026
4ac4753
[compiler] Track locations for dependencies (#35794)
josephsavona Feb 17, 2026
61db53c
[Native] Add RCTSelectableText as a recognized Text component (#35780)
NickGerleman Feb 18, 2026
4842fbe
[react-dom] Add support for `onFullscreenChange` and `onFullscreenErr…
chirokas Feb 18, 2026
3a2bee2
[DevTools] Fix alignment of breadcrumbs separator (#35817)
eps1lon Feb 18, 2026
f247eba
[Flight] Walk parsed JSON instead of using reviver for parsing RSC pa…
timneutkens Feb 19, 2026
38cd020
Don't outline Suspense boundaries with suspensey CSS during shell flu…
gnoff Feb 19, 2026
2ba3065
[Flight] Add support for transporting `Error.cause` (#35810)
eps1lon Feb 19, 2026
b16b768
[compiler] Feature flag cleanup (#35825)
josephsavona Feb 20, 2026
ab18f33
Fix context propagation through suspended Suspense boundaries (#35839)
acdlite Feb 21, 2026
8b6b11f
[compiler] Remove fallback compilation pipeline dead code (#35827)
josephsavona Feb 23, 2026
0dbb43b
[compiler] Add fault tolerance plan document (#35872)
josephsavona Feb 23, 2026
eca778c
[compiler] Phase 1: Add error accumulation infrastructure to Environm…
josephsavona Feb 23, 2026
426a394
[compiler] Phase 2+7: Wrap pipeline passes in tryRecord for fault tol…
josephsavona Feb 23, 2026
e3e5d95
[compiler] Phase 4 (batch 1): Update validation passes to record erro…
josephsavona Feb 23, 2026
9b2d801
[compiler] Phase 4 (batch 2), 5, 6: Update remaining passes for fault…
josephsavona Feb 24, 2026
59d7c27
[compiler] Phase 8: Add multi-error test fixture and update plan (#35…
josephsavona Feb 24, 2026
d6558f3
[compiler] Phase 3: Make lower() always produce HIRFunction (#35878)
josephsavona Feb 24, 2026
cebe42e
[compiler] Add fault tolerance test fixtures (#35879)
josephsavona Feb 24, 2026
8a33fb3
[compiler] Cleanup: consistent tryRecord() wrapping and error recordi…
josephsavona Feb 24, 2026
9075330
[compiler] Remove tryRecord, add catch-all error handling, fix remain…
josephsavona Feb 24, 2026
2e0927d
[compiler] Remove local CompilerError accumulators, emit directly to …
josephsavona Feb 24, 2026
011cede
[compiler] Rename mismatched variable names after type changes (#35883)
josephsavona Feb 24, 2026
c92c579
[compiler] Fix Pipeline.ts early-exit, formatting, and style issues (…
josephsavona Feb 24, 2026
b354bbd
[compiler] Update docs with fault tolerance summary, remove planning …
josephsavona Feb 24, 2026
bd76b45
[DevTools] Fix ReactDevToolsBackend module for AMD (#35891)
fullstackhacker Feb 24, 2026
c0060cf
[DevTools] Enable support for the React DevTools Client to connect to…
fullstackhacker Feb 24, 2026
e33071c
[compiler] Improved ref validation for non-mutating functions (#35893)
josephsavona Feb 24, 2026
074d96b
[flags] land `enableTrustedTypesIntegration` (#35816)
rickhanlonii Feb 25, 2026
a48e9e3
[RN] Fix timeStamp property of SyntheticEvent in React Native (#35912)
rubennorte Feb 26, 2026
98ce535
[RN] Expose event as a global variable during dispatch (#35913)
rubennorte Feb 26, 2026
6b113b7
[compiler] Deduplicate errors between ValidateExhaustiveDependencies …
josephsavona Feb 26, 2026
b4a8d29
fix: remove unused variable to fix linter (#35919)
hoxyq Feb 26, 2026
843d69f
[react-dom] Support `maskType` SVG prop (#35921)
sleitor Feb 27, 2026
e0cc720
[flags] Clean up `enableHiddenSubtreeInsertionEffectCleanup` (#35918)
hoxyq Feb 27, 2026
8ae014a
fix: detect setState in useEffect for anonymous component callbacks p…
fresh3nough Mar 1, 2026
9f2b4d7
babel fixes
fresh3nough Mar 1, 2026
99d6d02
fix: prevent catch parameter aliases from breaking scope boundaries i…
fresh3nough Mar 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 0 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,6 @@ module.exports = {
__IS_FIREFOX__: 'readonly',
__IS_EDGE__: 'readonly',
__IS_NATIVE__: 'readonly',
__IS_INTERNAL_MCP_BUILD__: 'readonly',
__IS_INTERNAL_VERSION__: 'readonly',
chrome: 'readonly',
},
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/runtime_eslint_plugin_e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
- "7"
- "8"
- "9"
- "10"
steps:
- uses: actions/checkout@v4
with:
Expand Down
47 changes: 30 additions & 17 deletions compiler/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ yarn snap -p <file-basename> -d
yarn snap -u
```

## Linting

```bash
# Run lint on the compiler source
yarn workspace babel-plugin-react-compiler lint
```

## Formatting

```bash
# Run prettier on all files (from the react root directory, not compiler/)
yarn prettier-all
```

## Compiling Arbitrary Files

Use `yarn snap compile` to compile any file (not just fixtures) with the React Compiler:
Expand Down Expand Up @@ -215,12 +229,12 @@ const UseEffectEventHook = addHook(
Feature flags are configured in `src/HIR/Environment.ts`, for example `enableJsxOutlining`. Test fixtures can override the active feature flags used for that fixture via a comment pragma on the first line of the fixture input, for example:

```javascript
// enableJsxOutlining @enableChangeVariableCodegen:false
// enableJsxOutlining @enableNameAnonymousFunctions:false

...code...
```

Would enable the `enableJsxOutlining` feature and disable the `enableChangeVariableCodegen` feature.
Would enable the `enableJsxOutlining` feature and disable the `enableNameAnonymousFunctions` feature.

## Debugging Tips

Expand All @@ -229,20 +243,19 @@ Would enable the `enableJsxOutlining` feature and disable the `enableChangeVaria
3. Look for `Impure`, `Render`, `Capture` effects on instructions
4. Check the pass ordering in Pipeline.ts to understand when effects are populated vs validated

## Error Handling for Unsupported Features
## Error Handling and Fault Tolerance

When the compiler encounters an unsupported but known pattern, use `CompilerError.throwTodo()` instead of `CompilerError.invariant()`. Todo errors cause graceful bailouts in production; Invariant errors are hard failures indicating unexpected/invalid states.
The compiler is fault-tolerant: it runs all passes and accumulates errors on the `Environment` rather than throwing on the first error. This lets users see all compilation errors at once.

```typescript
// Unsupported but expected pattern - graceful bailout
CompilerError.throwTodo({
reason: `Support [description of unsupported feature]`,
loc: terminal.loc,
});

// Invariant is for truly unexpected/invalid states - hard failure
CompilerError.invariant(false, {
reason: `Unexpected [thing]`,
loc: terminal.loc,
});
```
**Recording errors** — Passes record errors via `env.recordError(diagnostic)`. Errors are accumulated on `Environment.#errors` and checked at the end of the pipeline via `env.hasErrors()` / `env.aggregateErrors()`.

**`tryRecord()` wrapper** — In Pipeline.ts, validation passes are wrapped in `env.tryRecord(() => pass(hir))` which catches thrown `CompilerError`s (non-invariant) and records them. Infrastructure/transformation passes are NOT wrapped in `tryRecord()` because later passes depend on their output being structurally valid.

**Error categories:**
- `CompilerError.throwTodo()` — Unsupported but known pattern. Graceful bailout. Can be caught by `tryRecord()`.
- `CompilerError.invariant()` — Truly unexpected/invalid state. Always throws immediately, never caught by `tryRecord()`.
- Non-`CompilerError` exceptions — Always re-thrown.

**Key files:** `Environment.ts` (`recordError`, `tryRecord`, `hasErrors`, `aggregateErrors`), `Pipeline.ts` (pass orchestration), `Program.ts` (`tryCompileFunction` handles the `Result`).

**Test fixtures:** `__tests__/fixtures/compiler/fault-tolerance/` contains multi-error fixtures verifying all errors are reported.

This file was deleted.

31 changes: 0 additions & 31 deletions compiler/apps/playground/__tests__/e2e/page.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,37 +283,6 @@ test('error is displayed when config has validation error', async ({page}) => {
expect(output.replace(/\s+/g, ' ')).toContain('Unexpected compilationMode');
});

test('disableMemoizationForDebugging flag works as expected', async ({
page,
}) => {
const store: Store = {
source: TEST_SOURCE,
config: `import type { PluginOptions } from 'babel-plugin-react-compiler/dist';

({
environment: {
disableMemoizationForDebugging: true
}
} satisfies PluginOptions);`,
showInternals: false,
};
const hash = encodeStore(store);
await page.goto(`/#${hash}`, {waitUntil: 'networkidle'});
await page.waitForFunction(isMonacoLoaded);
await expandConfigs(page);
await page.screenshot({
fullPage: true,
path: 'test-results/07-config-disableMemoizationForDebugging-flag.png',
});

const text =
(await page.locator('.monaco-editor-output').allInnerTexts()) ?? [];
const output = await formatPrint(text);

expect(output).not.toEqual('');
expect(output).toMatchSnapshot('disableMemoizationForDebugging-output.txt');
});

test('error is displayed when source has syntax error', async ({page}) => {
const syntaxErrorSource = `function TestComponent(props) {
const oops = props.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,6 @@ The `occursCheck` method prevents infinite types by detecting when a type variab
- `DeclareContext` and `LoadContext` generate no type equations (intentionally untyped)
- `StoreContext` with `Const` kind does propagate the rvalue type to enable ref inference through context variables

### Event Handler Inference
When `enableInferEventHandlers` is enabled, JSX props starting with "on" (e.g., `onClick`) on built-in DOM elements (excluding web components with hyphens) are inferred as `Function<BuiltInEventHandlerId>`.

## TODOs
1. **Hook vs Function type ambiguity**:
> "TODO: callee could be a hook or a function, so this type equation isn't correct. We should change Hook to a subtype of Function or change unifier logic."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,6 @@ if ($[0] !== "source_hash_abc123") {
}
```

### Change Detection for Debugging
When `enableChangeDetectionForDebugging` is configured, additional code is generated to detect when cached values unexpectedly change.

### Labeled Breaks
Control flow with labeled breaks (for early returns or loop exits) uses `codegenLabel` to generate consistent label names:
Expand All @@ -231,7 +229,6 @@ type CodegenFunction = {
prunedMemoBlocks: number; // Scopes that were pruned
prunedMemoValues: number; // Values in pruned scopes
hasInferredEffect: boolean;
hasFireRewrite: boolean;
};
```

Expand Down

This file was deleted.

Loading
Loading