Skip to content

Commit 2af6822

Browse files
authored
[compiler] Claude file/settings (facebook#35523)
Initializes CLAUDE.md and a settings file for the compiler/ directory to help use claude with the compiler. Note that some of the commands here depend on changes to snap from the next PR. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/35523). * facebook#35607 * facebook#35298 * facebook#35596 * facebook#35573 * facebook#35595 * facebook#35539 * facebook#35537 * __->__ facebook#35523
1 parent 24d8716 commit 2af6822

File tree

3 files changed

+225
-0
lines changed

3 files changed

+225
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{
22
"permissions": {
33
"allow": [
4+
"Bash(yarn snap:*)",
5+
"Bash(yarn snap:build)",
46
"Bash(node scripts/enable-feature-flag.js:*)"
57
],
68
"deny": [],

compiler/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ dist
88
.vscode
99
!packages/playground/.vscode
1010
testfilter.txt
11+
.claude/settings.local.json
1112

1213
# forgive
1314
*.vsix
1415
.vscode-test
16+

compiler/CLAUDE.md

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
# React Compiler Knowledge Base
2+
3+
This document contains knowledge about the React Compiler gathered during development sessions. It serves as a reference for understanding the codebase architecture and key concepts.
4+
5+
## Project Structure
6+
7+
- `packages/babel-plugin-react-compiler/` - Main compiler package
8+
- `src/HIR/` - High-level Intermediate Representation types and utilities
9+
- `src/Inference/` - Effect inference passes (aliasing, mutation, etc.)
10+
- `src/Validation/` - Validation passes that check for errors
11+
- `src/Entrypoint/Pipeline.ts` - Main compilation pipeline with pass ordering
12+
- `src/__tests__/fixtures/compiler/` - Test fixtures
13+
- `error.todo-*.js` - Unsupported feature, correctly throws Todo error (graceful bailout)
14+
- `error.bug-*.js` - Known bug, throws wrong error type or incorrect behavior
15+
- `*.expect.md` - Expected output for each fixture
16+
17+
## Running Tests
18+
19+
```bash
20+
# Run all tests
21+
yarn snap
22+
23+
# Run tests matching a pattern
24+
# Example: yarn snap -p 'error.*'
25+
yarn snap -p <pattern>
26+
27+
# Run a single fixture in debug mode. Use the path relative to the __tests__/fixtures/compiler directory
28+
# For each step of compilation, outputs the step name and state of the compiled program
29+
# Example: yarn snap -p simple.js -d
30+
yarn snap -p <file-basename> -d
31+
32+
# Update fixture outputs (also works with -p)
33+
yarn snap -u
34+
```
35+
36+
## Version Control
37+
38+
This repository uses Sapling (`sl`) for version control. Sapling is similar to Mercurial: there is not staging area, but new/deleted files must be explicitlyu added/removed.
39+
40+
```bash
41+
# Check status
42+
sl status
43+
44+
# Add new files, remove deleted files
45+
sl addremove
46+
47+
# Commit all changes
48+
sl commit -m "Your commit message"
49+
50+
# Commit with multi-line message using heredoc
51+
sl commit -m "$(cat <<'EOF'
52+
Summary line
53+
54+
Detailed description here
55+
EOF
56+
)"
57+
```
58+
59+
## Key Concepts
60+
61+
### HIR (High-level Intermediate Representation)
62+
63+
The compiler converts source code to HIR for analysis. Key types in `src/HIR/HIR.ts`:
64+
65+
- **HIRFunction** - A function being compiled
66+
- `body.blocks` - Map of BasicBlocks
67+
- `context` - Captured variables from outer scope
68+
- `params` - Function parameters
69+
- `returns` - The function's return place
70+
- `aliasingEffects` - Effects that describe the function's behavior when called
71+
72+
- **Instruction** - A single operation
73+
- `lvalue` - The place being assigned to
74+
- `value` - The instruction kind (CallExpression, FunctionExpression, LoadLocal, etc.)
75+
- `effects` - Array of AliasingEffects for this instruction
76+
77+
- **Terminal** - Block terminators (return, branch, etc.)
78+
- `effects` - Array of AliasingEffects
79+
80+
- **Place** - A reference to a value
81+
- `identifier.id` - Unique IdentifierId
82+
83+
- **Phi nodes** - Join points for values from different control flow paths
84+
- Located at `block.phis`
85+
- `phi.place` - The result place
86+
- `phi.operands` - Map of predecessor block to source place
87+
88+
### AliasingEffects System
89+
90+
Effects describe data flow and operations. Defined in `src/Inference/AliasingEffects.ts`:
91+
92+
**Data Flow Effects:**
93+
- `Impure` - Marks a place as containing an impure value (e.g., Date.now() result, ref.current)
94+
- `Capture a -> b` - Value from `a` is captured into `b` (mutable capture)
95+
- `Alias a -> b` - `b` aliases `a`
96+
- `ImmutableCapture a -> b` - Immutable capture (like Capture but read-only)
97+
- `Assign a -> b` - Direct assignment
98+
- `MaybeAlias a -> b` - Possible aliasing
99+
- `CreateFrom a -> b` - Created from source
100+
101+
**Mutation Effects:**
102+
- `Mutate value` - Value is mutated
103+
- `MutateTransitive value` - Value and transitive captures are mutated
104+
- `MutateConditionally value` - May mutate
105+
- `MutateTransitiveConditionally value` - May mutate transitively
106+
107+
**Other Effects:**
108+
- `Render place` - Place is used in render context (JSX props, component return)
109+
- `Freeze place` - Place is frozen (made immutable)
110+
- `Create place` - New value created
111+
- `CreateFunction` - Function expression created, includes `captures` array
112+
- `Apply` - Function application with receiver, function, args, and result
113+
114+
### Hook Aliasing Signatures
115+
116+
Located in `src/HIR/Globals.ts`, hooks can define custom aliasing signatures to control how data flows through them.
117+
118+
**Structure:**
119+
```typescript
120+
aliasing: {
121+
receiver: '@receiver', // The hook function itself
122+
params: ['@param0'], // Named positional parameters
123+
rest: '@rest', // Rest parameters (or null)
124+
returns: '@returns', // Return value
125+
temporaries: [], // Temporary values during execution
126+
effects: [ // Array of effects to apply when hook is called
127+
{kind: 'Freeze', value: '@param0', reason: ValueReason.HookCaptured},
128+
{kind: 'Assign', from: '@param0', into: '@returns'},
129+
],
130+
}
131+
```
132+
133+
**Common patterns:**
134+
135+
1. **RenderHookAliasing** (useState, useContext, useMemo, useCallback):
136+
- Freezes arguments (`Freeze @rest`)
137+
- Marks arguments as render-time (`Render @rest`)
138+
- Creates frozen return value
139+
- Aliases arguments to return
140+
141+
2. **EffectHookAliasing** (useEffect, useLayoutEffect, useInsertionEffect):
142+
- Freezes function and deps
143+
- Creates internal effect object
144+
- Captures function and deps into effect
145+
- Returns undefined
146+
147+
3. **Event handler hooks** (useEffectEvent):
148+
- Freezes callback (`Freeze @fn`)
149+
- Aliases input to return (`Assign @fn -> @returns`)
150+
- NO Render effect (callback not called during render)
151+
152+
**Example: useEffectEvent**
153+
```typescript
154+
const UseEffectEventHook = addHook(
155+
DEFAULT_SHAPES,
156+
{
157+
positionalParams: [Effect.Freeze], // Takes one positional param
158+
restParam: null,
159+
returnType: {kind: 'Function', ...},
160+
calleeEffect: Effect.Read,
161+
hookKind: 'useEffectEvent',
162+
returnValueKind: ValueKind.Frozen,
163+
aliasing: {
164+
receiver: '@receiver',
165+
params: ['@fn'], // Name for the callback parameter
166+
rest: null,
167+
returns: '@returns',
168+
temporaries: [],
169+
effects: [
170+
{kind: 'Freeze', value: '@fn', reason: ValueReason.HookCaptured},
171+
{kind: 'Assign', from: '@fn', into: '@returns'},
172+
// Note: NO Render effect - callback is not called during render
173+
],
174+
},
175+
},
176+
BuiltInUseEffectEventId,
177+
);
178+
179+
// Add as both names for compatibility
180+
['useEffectEvent', UseEffectEventHook],
181+
['experimental_useEffectEvent', UseEffectEventHook],
182+
```
183+
184+
**Key insight:** If a hook is missing an `aliasing` config, it falls back to `DefaultNonmutatingHook` which includes a `Render` effect on all arguments. This can cause false positives for hooks like `useEffectEvent` whose callbacks are not called during render.
185+
186+
## Feature Flags
187+
188+
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:
189+
190+
```javascript
191+
// enableJsxOutlining @enableChangeVariableCodegen:false
192+
193+
...code...
194+
```
195+
196+
Would enable the `enableJsxOutlining` feature and disable the `enableChangeVariableCodegen` feature.
197+
198+
## Debugging Tips
199+
200+
1. Run `yarn snap -p <fixture>` to see full HIR output with effects
201+
2. Look for `@aliasingEffects=` on FunctionExpressions
202+
3. Look for `Impure`, `Render`, `Capture` effects on instructions
203+
4. Check the pass ordering in Pipeline.ts to understand when effects are populated vs validated
204+
205+
## Error Handling for Unsupported Features
206+
207+
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.
208+
209+
```typescript
210+
// Unsupported but expected pattern - graceful bailout
211+
CompilerError.throwTodo({
212+
reason: `Support [description of unsupported feature]`,
213+
loc: terminal.loc,
214+
});
215+
216+
// Invariant is for truly unexpected/invalid states - hard failure
217+
CompilerError.invariant(false, {
218+
reason: `Unexpected [thing]`,
219+
loc: terminal.loc,
220+
});
221+
```

0 commit comments

Comments
 (0)