Conversation
When compilationMode is set to 'annotation', module-level opt-in directives such as 'use memo' (placed at the top of a file) were silently ignored. Only function-level directives triggered compilation, contrary to the documented behavior that "place directives at the top of a file to affect all functions in that module". Root cause: both getReactFunctionType() and processFn() only inspected the function body's own directives (fn.node.body.directives) when deciding whether to compile in annotation mode. The program-level directives (program.node.directives) were never consulted. Fix: - Add hasModuleScopeOptIn to ProgramContext, computed once from tryFindDirectiveEnablingMemoization(program.node.directives). - In getReactFunctionType(), when compilationMode is 'annotation' and no function-level opt-in is found, fall back to hasModuleScopeOptIn before returning null. This ensures functions in the module are queued for compilation. - In processFn(), add !programContext.hasModuleScopeOptIn to the annotation mode skip guard so that the compiled function is emitted. Fixes react/react#35868
Greptile SummaryFixes module-level
Confidence Score: 4/5
Important Files Changed
Last reviewed commit: f7d2aa7 |
| hasModuleScopeOptIn: | ||
| tryFindDirectiveEnablingMemoization( | ||
| program.node.directives, | ||
| pass.opts, | ||
| ).unwrapOr(null) != null, |
There was a problem hiding this comment.
Silent error handling for module-level directives
When tryFindDirectiveEnablingMemoization returns an Err (e.g., a malformed dynamic gating directive at module scope), .unwrapOr(null) silently treats it as "no opt-in." This differs from the function-level handling in processFn (line 607-614), where errors are surfaced via handleError. A malformed module-level directive would be silently ignored rather than reported to the developer.
Consider handling the error case explicitly, similar to how function-level errors are handled:
const moduleScopeOptIn = tryFindDirectiveEnablingMemoization(
program.node.directives,
pass.opts,
);
if (moduleScopeOptIn.isErr()) {
handleError(moduleScopeOptIn.unwrapErr(), pass, null);
}
Then use moduleScopeOptIn.unwrapOr(null) != null for hasModuleScopeOptIn.
Prompt To Fix With AI
This is a comment left during a code review.
Path: compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts
Line: 417-421
Comment:
**Silent error handling for module-level directives**
When `tryFindDirectiveEnablingMemoization` returns an `Err` (e.g., a malformed dynamic gating directive at module scope), `.unwrapOr(null)` silently treats it as "no opt-in." This differs from the function-level handling in `processFn` (line 607-614), where errors are surfaced via `handleError`. A malformed module-level directive would be silently ignored rather than reported to the developer.
Consider handling the error case explicitly, similar to how function-level errors are handled:
```
const moduleScopeOptIn = tryFindDirectiveEnablingMemoization(
program.node.directives,
pass.opts,
);
if (moduleScopeOptIn.isErr()) {
handleError(moduleScopeOptIn.unwrapErr(), pass, null);
}
```
Then use `moduleScopeOptIn.unwrapOr(null) != null` for `hasModuleScopeOptIn`.
How can I resolve this? If you propose a fix, please make it concise.
Mirror of facebook/react#35870
Original author: sleitor
Summary
When
compilationModeis set to'annotation', module-level opt-in directives such as'use memo'placed at the top of a file were silently ignored. Only function-level directives (inside the function body) triggered compilation, contrary to the documented behavior:Root cause
Both
getReactFunctionType()andprocessFn()only inspected the function body's own directives (fn.node.body.directives) when deciding whether to compile in annotation mode. The program-level directives (program.node.directives) were never consulted.Fix
hasModuleScopeOptIntoProgramContext(computed once fromtryFindDirectiveEnablingMemoization(program.node.directives)).getReactFunctionType(): whencompilationModeis'annotation'and no function-level opt-in is found, fall back tohasModuleScopeOptInbefore returningnull. This ensures functions in the module are queued for compilation.processFn(): add!programContext.hasModuleScopeOptInto the annotation-mode skip guard so that the compiled function is actually emitted.use-memo-module-levelthat verifies'use memo'at module scope in annotation mode compiles the component.Behaviour table
'use memo''use memo''use memo'Fixes #35868